泛型结构中的运算符重载:我可以为特定类型(?)的泛型创建重载吗?
我正在 C# 中使用通用结构定义物理单位,一切进展顺利,直到出现错误:
二元运算符的参数之一必须是包含类型
当尝试重载数学运算符以便它们在不同单位之间进行转换时, 。所以,我有这样的事情:
public interface ScalarUnit { }
public class Duration : ScalarUnit { }
public struct Scalar<T> where T : ScalarUnit
{
public readonly double Value;
public Scalar(double Value)
{
this.Value = Value;
}
public static implicit operator double(Scalar<T> Value)
{
return Value.Value;
}
}
public interface VectorUnit { }
public class Displacement : VectorUnit { }
public class Velocity : VectorUnit { }
public struct Vector<T> where T : VectorUnit
{
#...
public static Vector<Velocity> operator /(Vector<Displacement> v1, Scalar<Duration> v2)
{
return new Vector<Velocity>(v1.Magnitude / v2, v1.Direction);
}
}
+
和 -
运算符没有任何错误,我只是在处理 Vector
,但是当我用一个单位替换T
时,它突然不喜欢它了。有办法让这项工作发挥作用吗?
我认为它会起作用,因为 Displacement
实现了 VectorUnit
接口,并且我在结构头中有 where T : VectorUnit
。我至少走在正确的轨道上吗?我是 C# 新手,所以有时我很难理解发生了什么。
I'm defining physical units in C#, using generic structs, and it was going okay until I got the error:
One of the parameters of a binary operator must be the containing type
when trying to overload the mathematical operators so that they convert between different units. So, I have something like this:
public interface ScalarUnit { }
public class Duration : ScalarUnit { }
public struct Scalar<T> where T : ScalarUnit
{
public readonly double Value;
public Scalar(double Value)
{
this.Value = Value;
}
public static implicit operator double(Scalar<T> Value)
{
return Value.Value;
}
}
public interface VectorUnit { }
public class Displacement : VectorUnit { }
public class Velocity : VectorUnit { }
public struct Vector<T> where T : VectorUnit
{
#...
public static Vector<Velocity> operator /(Vector<Displacement> v1, Scalar<Duration> v2)
{
return new Vector<Velocity>(v1.Magnitude / v2, v1.Direction);
}
}
There aren't any errors for the +
and -
operators, where I'm just working on a Vector<T>
, but when I substitute a unit for T
, suddenly it doesn't like it. Is there a way to make this work?
I figured it would work, since Displacement
implements the VectorUnit
interface, and I have where T : VectorUnit
in the struct header. Am I at least on the right track here? I'm new to C# so I have difficulty understanding what's going on sometimes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为运算符不能通用。
我可能会考虑对运算符中的类型进行硬编码,即如果 typeof(T).GetGenericParameters()[0] 是这个或那个类型等等。
我更喜欢的另一种方法是在返回 double 的所有子类中实现一个公共接口/基类,然后从运算符将其向下转换为该接口/b。类并获取要计算的值。
注意:根据约定,接口名称应符合始终以
I
开头(例如:IScalarUnit
)。I don't think operators can be generic.
I would maybe consider hardcoding the types in the operator, i.e. if typeof(T).GetGenericParameters()[0] is this or that type blah blah.
Another approach whouch I would even prefer is implementing a common interface/base class in all the subclasses that returns a double, then, from the operator, you cast it down to that interface/b. class and get the values to calculate.
Note: by convention, interface names should always start with
I
(example:IScalarUnit
).