是否存在可用于+运算符的通用约束?

时间:2011-05-13 19:57:30

标签: c# generics constraints

是否有一些'where'类型约束可以添加以使下面的代码编译?

public class Plus<T> : BinaryOperator<T> where T : ...
{
    public override T Evaluate(IContext<T> context)
    {
        return left.Evaluate(context) + right.Evaluate(context);
    }
}

谢谢:)

5 个答案:

答案 0 :(得分:20)

C#中没有这样的设备。但是有一些选择:

所以:

return (dynamic)left.Evaluate(context) + (dynamic)right.Evaluate(context);

return Operator.Add(left.Evaluate(context), right.Evaluate(context));

答案 1 :(得分:4)

C#中的Type参数约束非常有限,并且是listed here。所以答案是编译时检查没有。 如果T是您创建和管理的类型,那么可以采用的方法是

interface IAddable 
{
   IAddable Add(IAddable foo);
}

为所有类型实施IFoo,并使用where T: IAddable作为约束,并使用Add()代替+

答案 2 :(得分:1)

使用通用约束,您可以强制T

  • 是参考类型或值类型
  • 继承某个班级
  • 实现某些界面
  • 拥有无参数构造函数

但这就是全部。你不能强迫它上面存在静态operator+

答案 3 :(得分:0)

你的意思是通用约束吗?

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

答案 4 :(得分:0)

使用C# 8 default interface methods可以达到类似的目的,但可能无法解决您的确切用例:

您可以使用操作员的默认实现定义接口:

public interface IFoo
{
    double Value { get; }

    public static IFoo operator +(IFoo a, IFoo b)
    {
        return new Foo(a.Value + b.Value);
    }
}

public class Foo : IFoo
{
    public double Value { get; }

    public Foo(double value)
    {
        Value = value;
    }
}

并在这样的通用方法/类中使用它:

public static class Program
{
    public static void Main()
    {
        var f1 = new Foo(1);
        var f2 = new Foo(2);
        var sum = Add(f1, f2);
        Console.WriteLine(sum.Value);
    }

    public static IFoo Add<T>(T a, T b) where T : IFoo
    {
        return a + b;
    }
}