2014-11-25 31 views
2

所以,我遇到了以下“问题”,我真的很好奇它背后的原因。明确的投射算子vs与T

考虑以下几点:

public class B 
{ 

} 

public class A<T> 
{ 
    private void AFunc(T t) 
    { 
     FuncRequireB((B)t); // Not allowed 
     FuncRequireB(t as B); // Allowed 
    } 

    private void FuncRequireB(B b) 
    { 

    } 
} 

我知道优雅的解决方案是在类定义T作为B,但我想知道为什么“(B)t”和“T为B”在这种情况下不同。我知道“as”是安全的,所以如果转换无法完成,它可以生成为null,另一方面,如果转换不成功,显式强制抛出异常,但为什么编译器应该关心这个呢?在这种情况下,我看不到他们之间的区别。

预先感谢您!

+0

[C#泛型简介](http://msdn.microsoft.com/en-us/library/ms379564%28v=vs.80%29.aspx) – MethodMan 2014-11-25 14:17:10

+5

用'T'做的一切都比较好,但是再次,我来自英国。 – 2014-11-25 14:22:17

回答

5

区别在于通常是如果编译器知道一个转换,则转换可以执行用户定义的转换。对于泛型类型,编译器没有这些信息。如果你想只执行一条直线引用转换转换,你可以转换为object第一:

FuncRequireB((B)(object) t); 

可用的转换这方面从来没有非常我清楚,说实话 - 但它确实工作。

请注意,如果您可以约束TB类型兼容,则会更干净。如果它的位只适用于特定的类型参数,那么你的类型不是非常通用的。

+0

我认为,虽然你是正确的,但它是相当差的做法,并表明一个糟糕的设计。 – 2014-11-25 14:18:59

+0

@JamesRalston:因此是最后一段。 – 2014-11-25 14:21:40

+0

嗯,我只是想强调一下。对于静态类型语言为您提供的安全性来说,双重铸造是一种非常令人震惊的规避行为,我真的很想强调这一点。 “as”的运作方式与明确演员不同。它在不成功的拳击上返回'null'(并且null引用异常是一个完全不同的主题),但是这个投射非常危险。 – 2014-11-25 14:58:42