【问题标题】:How to use Generics to implement this? [duplicate]如何使用泛型来实现这一点? [复制]
【发布时间】:2017-02-14 08:54:50
【问题描述】:

泛型用于将逻辑与数据类型解耦。

public class Calc<T>
{
   public T Add(T a, T b)
   {
       return (a+b);
   }
}

但这会引发以下编译时错误

运算符 + 不能应用于类型 T。

我不明白为什么会这样。因为如果它允许来自 main.cs

main()
{
     Calc<int> obj = new Calc<int>();
     int c = obj.Add(10,20);
}

有人可以解释为什么我会收到构建错误吗??

【问题讨论】:

  • @ManfredRadlwimmer,我知道什么是泛型
  • 显然不是。如果您不对您的类型添加任何限制,则它只是一个object。对象没有+ 运算符。 C# 中的泛型与其他语言中的泛型并不完全相同。
  • @ManfredRadlwimmer 我应该如何操作。如果我通过 float 它应该返回 float,如果 int 返回 int
  • 可以在herehere 找到关于为什么不能对泛型类型施加运算符约束的其他信息

标签: c# generics


【解决方案1】:

C# 泛型不支持任意运算符。确切的(可能是虚拟的)方法必须在编译时知道泛型类型。由于您的示例中的泛型类型参数根本不受限制,因此您只能使用不包含 + 运算符的 object 类型的成员。

没有办法使用 C# 泛型来做你想做的事,抱歉。您能做的最好的事情是对一些已知类型(以及适当的类型转换,这对于值类型很棘手)进行一系列类型检查,或者使用反射(尤其是dynamic 会很好用)。

【讨论】:

    【解决方案2】:

    Calc&lt;T&gt; 这样的不受限制的泛型必须能够在应用任何类型的情况下进行编译,并非所有类型都支持+ 操作数,因此您的代码无法编译。这与您创建调用代码的特定类型无关。

    您可以限制T 的类型,从而通过Calc&lt;T&gt; where T:objectCalc&lt;T&gt; where T: IComparable 访问更多方法,这将允许您:

    public T CompareTo(T a, T b)
    {
       return (a.CompareTo(b));
    }
    

    因为所有T 现在都必须实现IComparable。不幸的是Int32 没有实现任何定义+ 运算符或任何加法方法的接口。所以没有办法实现你正在尝试的那个语句。

    【讨论】:

    • 内容丰富的帖子。谢谢
    【解决方案3】:

    C# 泛型不同于 C++ 模板。如果泛型类型没有使用方法的定义(在您的情况下为 operator+),则无法编译 C# 代码,而 C++ 编译器将此方法应用于实际的模板参数类型。

    【讨论】:

      【解决方案4】:

      不允许添加,因为不能保证传递的类型具有运算符 + 重载。
      有一种方法可以做到这一点,但只要您传递具有运算符 + 的类型,它就会起作用。否则,RuntimeBinderException 将被抛出。此外,对性能有一些影响,但除非代码对性能至关重要,否则应该不是问题。

      public T Add<T>(T a, T b)
      {
        dynamic da = a, db = b;
        return da + db;
      }
      

      【讨论】:

        猜你喜欢
        • 2016-11-17
        • 2021-11-15
        • 1970-01-01
        • 2012-01-24
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        • 2020-01-27
        • 1970-01-01
        相关资源
        最近更新 更多