假设我有一个通用的方法.调用方法与指定类型和调用没有它有什么区别.
什么时候强制指定类型?
Write(1);
Write<int>(1);
Write<string>("test");
Write("test");
private static void Write<T>(T param)
{
Console.WriteLine(param);
}
Run Code Online (Sandbox Code Playgroud)
编译器将尝试在编译时解析type参数.在可能的情况下,它是自动完成的,您无需指定显式类型.在所有其他情况下,当编译器无法确定类型参数时,编译器将抛出错误,您无法编译应用程序.
在您的示例中Write(1),参数1是类型int.所以编译器推断T必须是int,所以调用等同于 Write<int>(1).类似于Write("test"),"test"是类型string,因此编译器将推断它T是string.
这通常适用于传递给函数的参数的编译时类型.所以,如果你有一个编译时间类型的字符串object,T将是object:
object arg = "foo";
Write(arg); // arg is object
// this is equivalent to this:
Write<object>(arg);
Run Code Online (Sandbox Code Playgroud)
因此,虽然您传递的是字符串,但它的编译时间类型是object唯一的信息,编译器可以在这里使用.
此外,如果希望编译器使用与传递给它的编译时参数不同的类型,则可能需要显式指定类型参数.在上面的示例中,您可以使用Write<object>(1)哪个将导致整数1转换为object.但是,实际上这通常会破坏泛型方法的目的,即使您不需要访问实际参数的编译时类型,也可能会产生实际后果.例如,值类型在传递时会被装箱,object但泛型方法允许您将它们保存为值类型 - 请记住,泛型方法定义(同样适用于类型)等同于指定每个其他有效泛型类型参数的重载值(因此您通常拥有无限的方法副本).
当然,编译器的类型推断也适用于多个参数:
void Write<T1, T2>(T1 arg1, T2 arg2)
{ … }
Write(1, "foo");
// is equivalent to
Write<int, string>(1, "foo");
Run Code Online (Sandbox Code Playgroud)
但是,当编译器甚至无法推断出一个类型参数时,您必须在调用中指定所有这些参数.
| 归档时间: |
|
| 查看次数: |
61 次 |
| 最近记录: |