我有一个看起来像这样的结构:
public struct Vector2d<T> where T : Unit {
public double x;
public double y;
...
public static Vector2d<Length> operator * (Vector2d<Speed> speed, Vector2d<Duration> duration) {
return new Vector2d<Length>(speed.x * duration.x, speed.y * duration.y);
}
}
长度,速度和持续时间类型都是Unit的子类型。 (T也继承自单位)
然而,编译器说:
二元运算符的一个参数必须是包含类型。
这让我很奇怪,因为提供的类型是包含类型的子类。
为什么我试图做的非法?
我知道Vector2不是Vector2的子类,但我不是试图使用泛型类型的值。运算符中使用的所有数据都是Vector2类。
答案 0 :(得分:0)
根据MSDN page针对此错误:
二元运算符的定义指定两个参数,这些参数的类型不同于定义运算符的类或结构的类型。 在类或结构中定义运算符时,至少有一个参数必须是该类或结构的类型。
在您的情况下,您的运营商未使用Vector2d<T>
类型(您使用Vector2d<Speed>
和Vector2d<Duration>
。
答案 1 :(得分:0)
运算符对声明它们的类型的实例进行操作。例如:
string one = new string(new char[] { 'o', 'n', 'e' });
string two = new string(new char[] { 't', 'w', 'o' });
if (one == two) { // do something... };
我能够使用==
的原因是因为它是在String
类中实现的。
您班上也有一名操作员。所以让我们使用它。但要这样做,我需要创建一个Vector2d<T>
的实例,因为它是一个开放类型,我需要在实例化期间关闭它。
首先让我们这样做:
public class MyClass : Unit
{
}
现在让我们创建一个struct的实例:
var inst1 = new Vector2d<MyClass>();
var inst2 = new Vector2d<MyClass>();
这是有效的,因为MyClass
正在传递T
必须从Unit
派生的限制。好的,我现在要使用运算符:
// Ooops MyClass is not Speed or Duration
var result = inst1 * inst2;
这正是编译器强制执行该规则的原因,因为它希望确保操作符可以对该类型的实例进行操作。
在您的情况下,您只能为此Vector2d<T>
定义运算符:
public struct Vector2d<T> where T : Unit
{
public double x;
public double y;
public Vector2d(double x, double y)
{
this.x = x;
this.y = y;
}
public static Vector2d<T> operator *(Vector2d<T> speed, Vector2d<T> duration)
{
return new Vector2d<T>(speed.x * duration.x, speed.y * duration.y);
}
}
此外,您的操作员,您拥有它的方式根本不是通用的。它正在使用Speed
,Duration
和Length
,因此您正在使用这些类型。
错误二元运算符的参数之一必须是包含类型。是编译器避免让我们陷入这种麻烦的方法。我们应该感恩!