- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在为各种度量单位开发一个类库。我试图尽可能避免重复代码,这应该非常简单,因为从数学上讲,无论是将两个长度相加还是将两个速度相加都没有关系——您只需将它们转换为相同的单位,然后添加。我认为我可以使用基类和泛型很容易地做到这一点...
// A measurement consists of a Value (double) and
// a Unit (an Enum for the various unit types).
public class Measurement<TUnit>
where TUnit : struct
{
protected Measurement(double value, TUnit unit)
{
_value = value;
_unit = unit;
}
protected double _value;
protected TUnit _unit;
public double Value => _value;
public TUnit Unit => _unit;
...
// Conversion Methods - these will get overridden in the derived classes.
protected virtual double GetValueAs(TUnit unit) => throw new NotImplementedException();
...
// Operator overloads
public static Measurement<TUnit> operator +(Measurement<TUnit> left,
Measurement<TUnit> right)
{
return new Measurement<TUnit>(left.Value + right.GetValueAs(left.Unit), left.Unit);
}
}
并且像这样为每个单元派生此类:
public sealed class Length : Measurement<LengthUnit>
{
// Using a private constructor and public static factory methods
private Length(double value, LengthUnit unit)
: base(value, unit) { }
...
}
我的问题是每当我尝试使用任何返回 Measurement<TUnit>
的基类类型时,这些方法显然返回 Measurement<TUnit>
对象。
Length length1 = Length.FromMeters(1); // length1 is 1 meter
Length length2 = Length.FromMeters(2); // length2 is 2 meters
Length length3 = length1 + length2; // Error CS0266: Cannot implicitly convert type
// 'Measurement<LengthUnit>' to 'Length'.
// An explicit conversion exists (are you missing a cast?)
var varlength3 = length1 + length2; // This works, but varlength3 is type Measurement<LengthUnit>
// so I can't use any methods in the Length class.
我错过了什么?甚至可以做我想做的事吗?我是否必须硬着头皮将相同的代码复制到每个单元类中?
最佳答案
简答:当您需要从基类操作派生类时,可以通过实现Curiously Recurring Template Pattern 来完成。 ,它最初来自 C++,但也可以应用于 C#。
长答案:在您的情况下,基础 Measurement
类应该有一个额外的通用参数,即派生类类型。唯一的限制是,如果派生类具有带参数的构造函数,则不能在基类中使用 new
创建派生实例。在下面的示例中,我使用 MemberwiseClone 可能会解决问题。
public class Measurement<TUnit, TMeasurement>
where TUnit : struct
where TMeasurement: Measurement<TUnit, TMeasurement>
{
private readonly double _value;
protected Measurement(double value, TUnit unit)
{
_value = value;
Unit = unit;
}
protected double Value { get; set; }
public TUnit Unit { get; protected set; }
// Conversion Methods - these will get overridden in the derived classes.
protected virtual double GetValueAs(TUnit unit) => throw new NotImplementedException();
// Operator overloads
public static TMeasurement operator +(Measurement<TUnit, TMeasurement> left, Measurement<TUnit, TMeasurement> right)
{
//we cannot create new instance of derived class, TMeasurement, which is limitation of generics in C#, so need some workaround there
//Some kind of clone might be solution for that
var leftClone = (TMeasurement)left.MemberwiseClone();
var resultValue = leftClone.Value + right.GetValueAs(left.Unit);
leftClone.Unit = left.Unit;
leftClone.Value = resultValue;
return leftClone;
}
}
public struct LengthUnit
{
}
public sealed class LengthMeasurement : Measurement<LengthUnit, LengthMeasurement>
{
private LengthMeasurement(double value, LengthUnit unit): base(value, unit)
{
}
public static LengthMeasurement FromMeters(double meters) => throw new NotImplementedException();
}
class Program
{
static void Main(string[] args)
{
var length1 = LengthMeasurement.FromMeters(5);
var length2 = LengthMeasurement.FromMeters(10);
LengthMeasurement length3 = length1 + length2;
}
}
关于c# - 在 C# : How to ensure methods in the base class return the derived class's type? 的基类中使用泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59546683/
我的模型中有一个在私有(private)方法中运行的简单方法: def with_time_zone(zone) @old_time_zone = Time.zone Time.zone =
我想了解如何在代码中使用 Ensures()。正如 example 中给出的那样,如果我尝试使用 Ensures() 如下... int main(void) { int result = 0
当一个方法结束工作时我们也许需要进行清理工作.也许一个打开的文件需要关闭,缓冲区的数据应清空等等.如果对于每一个方法这里永远只有一个退出点,我们可以心安理得地将我们的清理代码放在一个地方并知道它会被
问题 我想检查 R 中的函数工厂是否“安全”。这里的“安全”意味着工厂创建的函数的结果仅取决于它们的参数,而不取决于全局变量。 描述 这是一个不安全的工厂: funfac_bad = function
如果我们有不同的由 webpack 创建的包并且我们 require.ensure在稍后的时间点动态传输+评估它的东西,它通过 jsonPadding 和一些 webpack js 魔法发生。如果我们
我正在开发一个小型 REST API。当我开始分析所有可能的故障场景(我必须处理这些故障场景以创建可靠且稳定的系统)时,我开始思考如何使我的 API 原子化。 如果我们采用通过 POST API 创建
我在 Xor 上有这段代码猫的对象 Xor.right(data).ensure(List(s"$name cannot be blank"))(_.nonEmpty) 现在由于 Xor 已被删除,我
我有一个带有 out 参数的方法,我想使用 Contract.Ensures() 指定当方法返回时,参数不会是 空。 基本上,这是: void M(out object o) { Contra
我开始使用 Code Contracts,虽然 Contract.Requires 非常简单,但我很难理解 Ensures 的实际作用。 我试过创建一个像这样的简单方法: static void Ma
我有一个问题 当我添加一些依赖项时,例如 github.com/jmoiron/sqlx 这个依赖项,我必须等待很长时间,然后它什么都不做,只显示消息“Fetching Sources” 我已经等了
我正在构建一个依赖预定作业的 Heroku 应用程序。我们以前使用 Heroku Scheduler,但时钟进程似乎更加灵活和健壮。所以现在我们使用时钟进程在特定时间/间隔将后台作业排入队列。 Her
我在 Scala 中有一个打字问题的小问题。在 Haskell 中,我可以这样做: add :: (Num a) => (a,a) -> (a,a) -> (a,a) 这样,我就可以扔进add任何支持
这是一个负责与服务器通信的类: public abstract class AbstractCommunicationChannel implements Runnable { static
我不明白为什么静态检查器说这个方法一切正常: public static int GetNonNegativeValue() { Contract.Ensures(Contract.Resul
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我有一个在 eventmachine react 器中运行的服务器,它监听用户的心跳以判断他们是否在线。当它开始/停止接收心跳时,它会适本地将用户标记为在线和离线。 我想将它全部包装在一个 ensur
我正在使用假设来测试将两个等长列表作为输入的函数。 import hypothesis.strategies as st from hypothesis import assume, given @g
假设我有这个: [Pure] public static TimeSpan Seconds(this int i) { Contract.Ensures(Contract.Result() =
这个问题在这里已经有了答案: How to specify types not allowed in a .NET Generics constraint? (4 个答案) 关闭 8 年前。 我有一
我的 .Net 4 应用程序中有以下代码: static void Main(string[] args) { Func(); } static string S = "1"; static
我是一名优秀的程序员,十分优秀!