C# 定义实现+;操作人员

C# 定义实现+;操作人员,c#,generics,operators,C#,Generics,Operators,可能重复: 我正在处理一个问题,目前它适用于ints,但我希望它适用于可以使用+运算符添加的所有类。有没有办法在泛型中定义这一点?比如说, public List<T> Foo<T>() where T : ISummable 这样,所有操作都在编译时强制执行:) 享受吧 C#4.0中的是一个新的关键字dynamic,允许您在运行时执行此操作。在以前的版本中,这是可能的,但对我来说太阴暗和狡猾了。但您可以始终传递一个将在泛型中执行添加的委托。否则这是不可能的,因为在编

可能重复:

我正在处理一个问题,目前它适用于
int
s,但我希望它适用于可以使用
+
运算符添加的所有类。有没有办法在泛型中定义这一点?比如说,

public List<T> Foo<T>() where T : ISummable
这样,所有操作都在编译时强制执行:)

享受吧

C#4.0中的是一个新的关键字dynamic,允许您在运行时执行此操作。在以前的版本中,这是可能的,但对我来说太阴暗和狡猾了。但您可以始终传递一个将在泛型中执行添加的委托。否则这是不可能的,因为在编译时没有可总结的、可编辑的,一般来说,没有办法知道某些东西是可添加的。如果你希望得到更多的评论,我会在以后补充。 比尔

  • 我的意思是,除了制作自己的IAdditive并用它们标记一些类型之外,但它不适用于例如ints
这是C#一个非常常见的新功能:能够指定比我们已有的更通用的参数约束。操作员是最常被问到的问题之一。然而,C#目前不支持这一点

可能的解决方法:

  • 将委托传递给任何需要进行加法的方法。这是最安全的类型选择,但是如果需要经常调用这样的方法,当然会很烦人。例如:

    public class Generic<T> {
        public void DoSomething(T anItem, T anotherItem, Func<T, T, T> add) {
            // instead of
            Blah(anItem + anotherItem);
            // have to write:
            Blah(add(anItem, anotherItem));
        }
    }
    
    Generic<int> genInt = ...;
    // and then instead of ...
    genInt.DoSomething(1, 2);
    // have to write:
    genInt.DoSomething(1, 2, (a, b) => a + b);
    
  • dynamic
    另一种可能的解决方法是使用
    dynamic
    ,但这是一种相当粗糙且完全不安全的方法:它将允许您传入任何类型并调用任何方法或运算符,并且只会在运行时崩溃,而不会在编译时崩溃


不,不是直接的。有一篇关于CodeProject的文章模拟了这一点。谢谢你的回复。你能给我发一个解决方案的链接吗?为什么不在ISummable中有一个可以添加两个T的方法,比如T add(T first,T second)?使用+运算符进行加法将涉及反射调用op_加法。@Timwi:除了动态将慢得多的事实之外。所以它没有过时。@TerroAustralis:如果我手头有这个url,我会发布它的。事实上,我记得几年前见过它,但这并不意味着我仍然拥有这个链接。谢谢,我可能最终会通过一个代表的方式。这似乎是一个合理的解决方案,不会给用户增加太多的工作量。谢谢你,伙计!谢谢你的回复!你对iAditive的评论一针见血。我无法将其用于Int和其他预实现的类/结构
public class Bar<T>
{
    private readonly IFoo<T,double> _operators;

    public Bar(IFoo<T, double> operators)
    {
        _operators = operators;
    }
}
private class Foo : IFoo<int, double>
{
    public double Add(int a, int b)
    {
        return (double)(a+b);
    }
    public double Subtract(int a, int b)
    {
        return (double)(a-b);
    }
}
Foo inttoDoubleOperations = new Foo();
Bar myClass = new Bar(Foo);
public class Generic<T> {
    public void DoSomething(T anItem, T anotherItem, Func<T, T, T> add) {
        // instead of
        Blah(anItem + anotherItem);
        // have to write:
        Blah(add(anItem, anotherItem));
    }
}

Generic<int> genInt = ...;
// and then instead of ...
genInt.DoSomething(1, 2);
// have to write:
genInt.DoSomething(1, 2, (a, b) => a + b);
public interface IAddable<T> {
    T Add(T other);
}
 
public struct Integer : IAddable<Integer> {
    public int Value;
    public Integer(int value) { Value = value; }
    public Integer Add(Integer other) { return new Integer(Value + other.Value); }
}

// then instead of
Generic<int> blah = ...;
// have to write:
Generic<Integer> blah = ...;