“从任何类类型 S 到任何接口类型 T,假设 S 未被密封并且假设 S 不实现 T。”是什么意思?实际上是什么意思?
“从任何类类型 S 到任何接口类型 T,前提是 S 未密封并且假设 S 不实现 T”。实际上是什么意思?
我在 C# 语言规范 此处:
6.2.4 显式引用转换
显式引用转换 是:
- ...
- 从任何类类型 S 到任何接口类型 T,前提是 S 不是 密封且前提是 S 不 实施T。
,但我不确定我是否理解“假设S不实现T”的真正含义。
例如:
class S {}//not sealed, nor does it implement T
interface T {}
...
T t = (T)new S();//will throw InvalidCastException.
难道规范中只是枚举了表达显式引用转换的所有语法正确的方法,而不管它是否会抛出异常?或者这是否意味着我不知道的其他事情(到目前为止)?
提前致谢。
What does "From any class-type S to any interface-type T, provided S is not sealed and provided S does not implement T." actually mean?
I came across this in the C# Language Specifications here:
6.2.4 Explicit reference conversions
The explicit reference conversions
are:
- ...
- From any class-type S to any interface-type T, provided S is not
sealed and provided S does not
implement T.
I can understand what "provided S is not sealed" means, but I'm not sure if I understand what "provided S does not implement T" really mean.
For example:
class S {}//not sealed, nor does it implement T
interface T {}
...
T t = (T)new S();//will throw InvalidCastException.
Could it be that it is in the specs only to enumerate all syntactically correct ways of expressing an explicit reference conversion, regardless of whether it will throw an exception or not? Or does it mean some other thing which I do not know (as of now)?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看起来这都是关于用户定义的转换。
如果 S 没有实现 T,那么你绝对不能将类 S 转换为接口 T。
It seems it's all about user-defined conversions.
You definitely can't cast class S to interface T if S does not implement T.
你确定这不是文中的错误吗?
假设 S 确实实现了 T。
编辑:我找到了参考:http://msdn.microsoft.com/en-us/library/aa691291(v=VS.71).aspx
这是明确的 > 引用转换,意味着不是隐式的!
所以这句话“从任何类类型S到任何接口类型T,假设S没有密封并且假设S不实现T”是正确的,它不能是隐式转换,因此它必须是显式的(并且不保证它会成功)。
Are you sure it's not an error in the text?
Provided S does implement T.
Edit: I've found the reference: http://msdn.microsoft.com/en-us/library/aa691291(v=VS.71).aspx
That is explicit reference conversion, it means that is not implicit!
So the sentence "From any class-typeS to any interface-typeT, provided S is not sealed and provided S does not implement T" is correct, it can't be an implicit conversion, so it must be explicit (and is not guaranteed it would succeed).
规范中写道:
换句话说,这里列出的转换类型是显式转换,由于两种类型之间缺乏显式关系,编译器无法在编译时检查这种转换是否可能且有效。此类转换尝试将在程序执行期间解决,如果转换不可能,则可能会导致异常。
运行时显式转换的典型示例可能会失败,但也可能会成功,即从接口类型 S 到接口类型 T 的转换,其中 S 和 T 不相关。成功取决于底层对象是否实现这两个接口。
您询问的情况的一个特别奇怪的例子 - 从类类型 S 到接口类型 T,其中 S 不实现 T(并且未密封),当 S 是 COM 对象,而 T 是 COM 接口而不是在类型库中显式列出,由 coclass 实现。在这种情况下,转换可能会失败,但也可能会成功,具体取决于 coclass 的特定 IUnknown::QueryInterface 实现是什么。 (请注意,从技术上讲,本例中的 coclass 正在实现该接口,但不会将其广告给编译器)
当然,@Henk Holterman 的 S2 示例:S, T 也是一个可以成功转换的好例子。
The spec goes to say:
In other words, the types of conversion listed here are those explicit conversion, where the compiler cannot make the check if such conversion is possible and valid at compile time, due to a lack of explicit relationship between the two types. Such conversion attempt will be resolved during the execution of the program and might result in an exception, if the conversion is impossible.
The canonical example of a run-time explicit conversion that might fail, but also might succeed, would be conversion from interface-type S to interface-type T, where S and T are not related. The success depends on whether the underlying object implements both interfaces or not.
Particular curious example of the case you asked about - from class-type S to interface-type T, where S does not implement T (and is not sealed), would be when S is a COM object, and T is a COM interface not explicitly listed in the type library as implemented by the coclass. In this case, the conversion might fail, but it also might succeed, depending on what the particular IUnknown::QueryInterface implementation of the coclass is. (Note that technically, the coclass in this case is implementing the interface, but is not advertising it to the compiler)
And of course, @Henk Holterman example of S2 : S, T is also a good example where that conversion can succeed.
双关语在“未密封”部分:
是的,编译器必须允许它,除非它知道转换是不可能的。
如果您查看
T t = (T)s;
,如果 S 被密封,那么编译器可以确定地知道转换是不可能的。但是对于未密封的S
,它必须消除s
引用S2
类型的可能性,这是不实际/不可能的( S2 可能位于另一个组件中)。The pun is in the "not sealed" part:
Yes, the compiler must allow it unless it knows the conversion to be impossible.
If you look at
T t = (T)s;
, if S was sealed then the compiler could know with certainty that the conversion was impossible. But with an unsealedS
, it would have to eliminate the possibility thats
is referencing anS2
type, and that is not practical/possible (S2 could be in another assembly).