【问题标题】:Defining operators for specific instances of a generic为泛型的特定实例定义运算符
【发布时间】:2023-03-29 04:03:01
【问题描述】:

我正在尝试实现通用 Vector3 结构,并且当类型 T 是数字(int、float、double、long、short)时,我的结构具有允许基本数学运算的运算符

我曾认为这样做的方法是只为每个类似的东西定义 4 个基本运算符

public static Vector3<int> operator +(Vector3<int> left, Vector3<int> right) 但这给了我一个错误,即至少有一个参数必须是包含类型(在这种情况下是 Vector3)

我有理由相信有一种方法可以定义 Vector3 泛型,并且仍然具有标准运算符的便利性,但我似乎无法弄清楚我需要在语法上编写什么。

【问题讨论】:

  • 公共结构 Vector3 { T x; y; Tz; }
  • 我找不到Vector3<T> 课程。这是你写的吗?
  • @Azeranth 请使用您正在创建的结构以及不起作用的运算符重载更新您的问题(cmets 中的代码没有帮助)。
  • @Rufus 该链接适用于Vector3,而不是Vector3<T>。还有一个Vector<T>。但是我知道没有Vector3<T>
  • 也许this question 有一个对这里有帮助的答案?

标签: c# generics inheritance operator-overloading


【解决方案1】:

我相信你正在尝试做这样的事情:

public class Vector3<T>
{ 
    T x; T y; T z; 

    public static Vector3<int> operator + (Vector3<int> lhs, Vector3<int> rhs)
    {
        //Stuff
    }
}

这是不允许的。为什么不?想象一下你写了一个这样的方法:

public static void Foo<T>()
{
    var lhs = new Vector3<T>();
    var rhs = new Vector3<T>();

    var result = lhs + rhs;
}

编译器是否应该允许它编译?因为这样可行:

Foo<int>();

但这会失败:

Foo<string>();

因为编译器不能保证它会工作,所以是不允许的。

如果您迫切希望为某些类型的 Vector3 实现运算符重载,则必须对其进行子类化:

public class Vector3Int : Vector3<int>
{
    public static Vector3Int operator + (Vector3Int lhs, Vector3Int rhs)
    {
        //Stuff
    }
}

那会奏效。请注意,我必须将 struct 更改为 class,因为您不能继承结构。

【讨论】:

  • 但是那段错误代码应该告诉我“无法将运算符'+'应用于类型“Vector3”和“Vector3”。要求我只在类型是已知的或明确给出的
  • 编译器怎么可能知道T 将传递给Foo&lt;T&gt; 的调用?请记住,此代码可以编译为程序集并从您甚至没有源代码的程序中调用。
  • 好吧,它不会,因此错误,因为显式类型是 T。但我应该能够声明一个 List> Foo;然后说 Foo[0] += Foo[1]
  • 泛型不是这样工作的。泛型必须处理任何类型的T,受type constraints 约束。如果你想挑选特定的类型,它不是泛型的——你可以使用传统的多态性或其他一些编程结构,但不能使用泛型。
猜你喜欢
  • 2011-04-05
  • 2021-06-11
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
相关资源
最近更新 更多