2010-10-05 76 views
2

鉴于Tuple.Create返回类型

void foo(Tuple<object> t) 
{ 

} 
void bar() 
{ 
    foo(Tuple.Create("hello")); 
} 

C#编译器返回

error CS1502: The best overloaded method match for 'foo(System.Tuple<object>)' has some invalid arguments 
error CS1503: Argument 1: cannot convert from 'System.Tuple<string>' to 'System.Tuple<object>' 

添加明确的类型Tuple.Create违背了它的目的。我如何说服编译器接受代码?

FWIW,我认为C++不存在这个问题:http://live.boost.org/doc/libs/1_33_1/libs/tuple/doc/tuple_users_guide.html#constructing_tuples

+1

如果你不在乎被强类型化为什么不使用void foo(params object [] args)? – cordialgerm 2010-10-05 21:55:13

回答

4

这是每天出现的相同泛型类型的协方差问题。根本不可能将Foo<T>转换为Foo<SubT>,反之亦然。从.NET 4开始,它支持 - 但仅限于接口和委托,并且通过声明Foo<out T1>明确指定泛型类型参数作为变体。

+0

反正它不支持类;只有代表和接口。 – thecoop 2010-10-05 21:59:54

+0

@thecoop哎呀,忘了那一点。谢谢 – 2010-10-05 22:02:39

2

您正试图将Tuple<string>转换为Tuple<object>,您无法这么做 - 通用差异仅支持接口和委托。您需要显式地指定类型参数的Tuple.Create

void bar() 
{ 
    foo(Tuple.Create<object>("hello")); 
} 
4

您可以通过使用Tuple<object>,但使用Tuple<T>

void foo<T>(Tuple<T> t) 

如果你不想这样做,使代码编译,你只需要就可以将显式的带到Tuple.Create方法的对象中。

Tuple.Create<object>("Hello"); 
Tuple.Create((object)"Hello"); 

考虑,如果你能Tuple<object>然后通过在Tuple<string>。如果你的签名是

void(ref Tuple<object> t) 

没有什么阻止你在那个方法

t = new Tuple<object>(1); 

写现在你刚刚把1元组中,只允许字符串。当然,这是Tuple本质上只读的角落案例,所以你需要一个ref参数,但它仍是一个问题。