typeof(T)vs <t> </t>

时间:2011-04-01 17:58:35

标签: .net generics typeof

在.NET中,似乎有两种方法可以将类型传递给方法或类。第一种是通过泛型,我们将类型作为特殊参数传递。

如:

var list = new List<MyClass>();

另一种方法是明确使用typeof运算符,例如:

var pe = Expression.ParameterExpression(typeof(MyClass), "myinstance");

我的问题是关于需要类型参数的方法的统一接口的差异。为什么上述陈述不能如下进行?:

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

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

谢谢。

4 个答案:

答案 0 :(得分:6)

第一种方法允许您在运行时计算所需的类型。

Expression.ParameterExpression(CalculateType(), "myinstance");

就个人而言,我不介意看到一个重载,这肯定会使编译时定义的类型的代码更加清晰。

答案 1 :(得分:3)

考虑这种方法签名。

public object MyGetInstanceOfType(Type theType)

虽然可能会返回相应类型的实例,但编译器无法对其进行验证...直到运行时才会知道theType(在涉及编译器之后)。

与此形成对比:

public T MyGetInstanceOfType<T>()

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

答案 2 :(得分:2)

使用var list = new List<MyClass>();,List类在编译时被告知它与特定类型相关联。然后,编译器可以进行类型检查,以确保只将MyClass的元素添加到列表中。

使用var pe = Expression.ParameterExpression(typeof(MyClass), "myinstance");表达式在运行时被告知它正在使用哪种类型的参数。编译器无法使用此方法进行强类型检查。对于在编译时无法确定事物的动态代码更好,但这些情况很少见(尽管表达式树是其中之一)。

答案 3 :(得分:0)

从技术上讲,可以轻松创建通用版本,因为它可以调用类似的类型的重载:

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

在这种情况下,使用通用并不会给你太多。如果其中一个参数是T类型或返回值是T类型,那么您将根据指定的类型参数获得强类型。

添加参数方法的通用版本不会使其输入更多或更少。