Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#运算符重载使用泛型';s子类_C#_Generics_Operator Overloading_Operators - Fatal编程技术网

C#运算符重载使用泛型';s子类

C#运算符重载使用泛型';s子类,c#,generics,operator-overloading,operators,C#,Generics,Operator Overloading,Operators,我有一个结构,看起来像这样: 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

我有一个结构,看起来像这样:

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);
    }
}
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);
    }
}
public struct Vector2d其中T:Unit{
公共双x;
公共双y;
...
公共静态矢量2D操作符*(矢量2D速度,矢量2D持续时间){
返回新矢量2D(速度.x*持续时间.x,速度.y*持续时间.y);
}
}
长度、速度和持续时间类型都是单位的子类型。(T也从单元继承)

然而,编译器说:

二进制运算符的参数之一必须是包含类型

这让我感到奇怪,因为提供的类型是包含类型的子类

为什么我试图做的事情是非法的

我知道Vector2不是Vector2的子类,但我并没有尝试使用泛型类型的值。运算符中使用的所有数据都是Vector2类。

根据此错误的定义:

二元运算符的定义指定两个参数的类型不同于定义该运算符的类或结构的类型。 在类或结构中定义运算符时,至少有一个参数必须是该类或结构的类型


在您的情况下,运算符不使用
Vector2d
类型(您使用的是
Vector2d
Vector2d
,运算符对声明它们的类型的实例进行操作。例如:

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
的实例,因为它是一个开放类型,所以我需要在实例化期间关闭它

那么让我们先做这个:

public class MyClass : Unit
{
}
现在,让我们创建一个结构实例:

var inst1 = new Vector2d<MyClass>();
var inst2 = new Vector2d<MyClass>();
这正是编译器之所以强制执行该规则的原因,因为它希望确保运算符可以对该类型的实例进行操作

在您的情况下,只能定义
Vector2d
的运算符,如下所示:

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);
    }
}
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);
    }
}
public struct Vector2d其中T:Unit
{
公共双x;
公共双y;
公共向量2D(双x,双y)
{
这个.x=x;
这个。y=y;
}
公共静态矢量2D操作符*(矢量2D速度,矢量2D持续时间)
{
返回新矢量2D(速度.x*持续时间.x,速度.y*持续时间.y);
}
}
此外,您的运算符的使用方式根本不是通用的。它使用的是
速度
持续时间
长度
,因此您可以使用这些类型


错误二进制运算符的参数之一必须是包含类型。这是编译器避免我们陷入此类麻烦的方法。我们应该感谢!

这是非法的,因为语言设计者将其定为非法。错误消息准确地告诉您C#规范描述的约束。编译器如果你想知道“为什么”的话你需要询问语言设计师,即使这样,他们的推理也可能主要基于他们自己的观点。不确定为什么这个问题被否决了……完全有效的问题,带有代码和清晰的问题。+1来自我。我建议不要试图通过泛型来表示单元分析。单元是真正需要b的东西内置到语言中。例如,请参见F#的单位类型注释。因此运算符必须应用于该类型的所有实例,而不仅仅是子集。明白了。