typeof(T)与<T>的区别

6
在.NET中,似乎有两种方法可以将类型传递给方法或类。第一种是通过泛型,在其中我们将类型作为特殊参数传递。
例如:
var list = new List<MyClass>();

另一种方法是明确使用 typeof 运算符,例如:
var pe = Expression.ParameterExpression(typeof(MyClass), "myinstance");

我的问题与需要类型参数的方法的统一接口不一致有关。为什么不能按照以下方式完成上述语句:

var pe = Expression.ParameterExpression<MyClass>("myinstance");

是因为编译器在处理泛型参数时需要两个语义上的不同吗?当编译器处理一个泛型参数时,它是否只是执行lambda演算中的替换操作?而typeof样式的方法需要一个实际的Type类实例来推断属性和属性?

谢谢。


3
那些“特殊参数”被称为类型参数,这样你就知道了 :) - Richard Szalay
想象一下太平洋的广阔海域。T在日本,而T在加利福尼亚。T到夏威夷的速度比T快一千倍。 - Hans Passant
@Richard。我知道。我不知道为什么我会这样表达。泛型在学术上被称为参数多态性,因此类型参数紧随其后。 - Nicholas Mancuso
4个回答

6
第一种方法允许您在运行时计算所需的类型。
Expression.ParameterExpression(CalculateType(), "myinstance");

个人而言,我不介意看到一种过载机制,这将使编译时定义类型的代码更加简洁。


多么显而易见的原因!我简直不能相信我竟然忽略了它!谢谢。 - Nicholas Mancuso

3
考虑下面的方法签名:
public object MyGetInstanceOfType(Type theType)

尽管返回了适当类型的实例,但编译器无法验证它... 在运行时之前(比编译器涉及的时间要晚得多),才会知道theType是什么。

与此形成对比的是:

public T MyGetInstanceOfType<T>()

每次调用此方法时,编译器都知道类型。它可以保证方法的返回值,因为它知道所有调用中的类型。


2
使用 var list = new List<MyClass>();,List 类在编译时就被告知它与一个特定类型相关联。编译器可以进行类型检查,以确保只有 MyClass 的元素添加到列表中。
使用 var pe = Expression.ParameterExpression(typeof(MyClass), "myinstance");,表达式在运行时告诉了它正在使用的参数类型。编译器无法使用这种方法进行强类型检查。这对于动态代码更好,因为在编译时无法确定其中的内容,但这些情况很少见(尽管表达式树是其中之一)。

0

从技术上讲,可以轻松创建一个通用版本,因为它可以调用接受类型的重载,例如:

public static ParameterExpression Parameter<T>(string name) {
    return Parameter(typeof(T), name);
}

然而,在这种情况下,使用泛型并没有带来太多好处。如果其中一个参数的类型是T或返回值的类型是T,那么您将基于指定的类型参数获得强类型。

添加Parameter方法的泛型版本并不会使其更加强类型或弱类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接