作为一名熟练的c#程序员,什么陷阱在Java类型参数推理规则中等着我?

时间:2011-06-09 10:44:30

标签: c# java generics type-inference

或换句话说

  

泛型类型的类型参数推断的主要区别是什么?   在C#和Java之间?

我正在寻找能够在几分钟内被熟练的C#开发人员阅读和理解的答案。

2 个答案:

答案 0 :(得分:3)

Java与&之间的主要区别C#泛型是Java泛型由编译器强制执行,并根据需要插入所需的强制转换。字节码不引用泛型类型,这称为“type erasure”。

在C#中,泛型存在于中间语言中,因此没有擦除。因此,您可以使用反射来读取泛型类型参数。

请参阅此相关问题:

What are the differences between Generics in C# and Java... and Templates in C++?

答案 1 :(得分:2)

我发现人们最困惑的一件事是:如果类型参数只出现在返回类型中,编译器就会有推断它的问题。

<T> T foo();

foo(); // fail, no idea what T is

这个例子是可以理解的,但以下不是

void bar(String s){..}

bar( foo() ); // fail, compiler can't infer T=String

人们非常沮丧,编译器无法推断出这样的简单案例。

仅在2个上下文中(均为“赋值转换”),Java可以推断出T

String s = foo(); // ok, T=String

String doo()
{
    return foo(); // ok, T=String
}

(虽然它编译,但它非常危险。foo()如何知道它应该返回String?由于类型擦除,它在运行时无法访问T。如果即使在这两种情况下也不允许推理,那会更好。)

当然,当推理失败时,您总是可以提供明确的类型参数。