2014-01-30 25 views
2

有没有办法让这段代码编译?C语言中泛型类的二元运算符

class Foo<T> 
{ 
    ... 
} 

... 

var a = new Foo<int>(); 
var b = new Foo<string>(); 
var c = a + b; 

看来,C#允许指定既不operator+(Foo<int> a, Foo<string> b),也不operator+<U>(Foo<T> a, Foo<U> b)。鉴于我可以很容易地创建operator +(Foo a, Bar b)非通用FooBar,这个限制,如果存在,似乎有点奇怪。

+0

http://stackoverflow.com/a/756995/961113 – Habib

+1

我不认为这个问题有很多事情要做我的。我错过了明显的东西吗? – hr0nix

+0

这一个应该是相关的:http://stackoverflow.com/questions/5905563/c-sharp-generic-operators –

回答

0

在C#中没有通用的运算符支持。此外,您不能声明通用类型限制,这意味着“此通用类型有一些运算符”。有办法解决这个问题。

首先是使用表达式。你可以在Marc Gravells article中阅读。

二是使用动态。例如,通用的Add()方法可能看起来像这样没有例外:

public static T Add<T>(T arg1, T arg2) 
{ 
    dynamic a1 = arg1; 
    dynamic a2 = arg2; 
    return a1 + a2; 
} 

在这两种情况下,你可能必须在运行时的一些不愉快的意外。

但据我所知,你想添加两个不同类型的对象。 Foo < int>Foo < string>不一样,我认为这甚至没有意义。这个添加的结果是什么?反正你可以宣布你的方法是这样的:

public static T1 Add<T1, T2>(T1 arg1, T2 arg2) 
{ 
    dynamic a1 = arg1; 
    dynamic a2 = arg2; 
    return a1 + a2; 
} 

这种方法可以成功地添加INT(但不是反之亦然):

Console.WriteLine(Add("hello", 1)); 

您可以尝试添加任何东西到什么但是您必须具有合适的运算符重载版本才能没有例外。又如:

class MyClass<T> 
{ 

    public static MyClass<T> operator +(MyClass<T> c1, MyClass<int> c2) 
    { 
     return new MyClass<T>(); 
    } 

} 

//... 

// Add MyClass<string> to MyClass<int>. 
// As you can see we have appropriate version of operator overloading for doing this without exceptions. 
var c1 = new MyClass<string>(); 
var c2 = new MyClass<int>(); 
var res = Add(c1, c2); 
+0

也许它应该在问题文本中得到澄清:我不打算对加号运算符中的通用值进行任何实际添加,因此答案的第一部分不相关。我想要做的是隐式地构建一个对应于涉及我的自定义类型成员的算术表达式的树。完全指定的只有一个参数类型的重载似乎可以做到这一点,谢谢。 – hr0nix