泛型方法的类型参数的类型推断
问题描述:
我是堆栈溢出的一个newby,所以请在我身上轻松一下!我正在深入阅读C#,但我遇到了一个我不相信的场景。对网络的快速搜索也没有发现任何结果。泛型方法的类型参数的类型推断
说我定义以下重载方法:
void AreEqual<T>(T expected, T actual)
void AreEqual(object expected, object actual)
如果我打电话AreEqual()
没有指定类型参数:
AreEqual("Hello", "Hello")
调用该方法的通用或非通用版本?泛型方法是在推断出类型参数的情况下调用的,还是调用方法参数隐式转换为System.Object
的非泛型方法?
我希望我的问题很清楚。提前感谢您的任何建议。
答
该仿制药可以生成功能AreEqual(string, string)
。这比AreEqual(object, object)
更接近匹配,因此选择通用函数。
有趣的是,即使编译器会导致约束违规错误,编译器也会选择这个通用函数。
请看下面的例子:
using System.Diagnostics;
namespace ConsoleSandbox
{
interface IBar
{
}
class Program
{
static void Foo<T>(T obj1) where T: IBar
{
Trace.WriteLine("Inside Foo<T>");
}
static void Foo(object obj)
{
Trace.WriteLine("Inside Foo Object");
}
static void Main(string[] args)
{
Foo("Hello");
}
}
}
即使在这里,会选择在非通用版本的通用版本。然后你得到这个错误:
The type 'string' cannot be used as type parameter 'T' in the generic type or method 'ConsoleSandbox.Program.Foo(T)'. There is no implicit reference conversion from 'string' to 'ConsoleSandbox.IBar'.
但如果添加了一个功能Foo(string obj1)
它会工作。
你当然可以写一些简单的代码来检查这个... – 2012-01-28 01:43:21
http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx – 2012-01-28 01:56:51
@米奇麦 - 真实的,但我不会做我的第一篇文章。它对其他人在这里看到答案很有用。 – zekesteer 2012-01-28 02:01:51