【发布时间】:2015-08-07 15:18:55
【问题描述】:
我很难理解为什么在这个简单的示例中没有选择正确的重载。查看 7.5.3.2 Better 函数成员下的 C# 5 spec,似乎它应该能够选择非泛型重载,但 object 参数似乎以某种我不理解的方式影响了决策。我遇到的问题是,如果不将参数转换为object,我就无法调用Foo(object) 的非通用版本。从错误来看,它似乎不受支持,我希望有人能解释原因。
public class A
{
public string Type { get { return "non-generic"; } }
}
public class A<T>
{
public string Type { get { return "generic"; } }
}
class Program
{
// (In reality only one of the variants below can be uncommented.)
static void Main(string[] args)
{
// This works fine and calls the generic overload as expected
A<string> x = Foo<string>("foobar");
// This results in a compile time error
// CS0029: Cannot implicitly convert type 'A<string>' to 'A'
A x = Foo("foobar");
// This works, but ends up calling the generic overload
var x = Foo("foobar");
// This works fine and calls the non-generic overload as expected
object a = "foobar";
var x = Foo(a);
// This works fine and calls the non-generic overload as expected
A x = Foo((object)"foobar");
// By using dynamic we're able to get rid of the compile-time error, but get a
// runtime exception.
// RuntimeBinderException: Cannot implicitly convert type 'A<string>' to 'A'
A x = Foo((dynamic)"foobar");
Console.WriteLine(x.Type);
Console.ReadLine();
}
private static A Foo(object x)
{
return new A();
}
private static A<T> Foo<T>(T x)
{
return new A<T>();
}
}
【问题讨论】:
-
我认为编译时错误是因为 Foo("foobar") 正在为您创建一个 A
(通用),然后您尝试将其放入 A 类型的变量(非通用的)。就编译器而言,它们是两种完全不同的类型。如果您要使用: var x = Foo("foobar");它可能会编译 -
你是对的 var x = Foo("foobar");编译并运行。它还调用泛型重载。如果不显式转换为对象或传递对象,是否无法调用非泛型重载?
标签: c# generics .net-4.5 visual-studio-2015 overloading