C#“是” 运算符 - 这是反射吗?
今天一位同事问了我一个有趣的问题 - C# 关键字/运算符“is”是否被视为反射?
object tmp = "a string";
if(tmp is String)
{
}
这个运算符在幕后是如何实现的? 是否需要反思或反省? 或者由于语言的强类型性质,对象的类型是否可以作为内存中对象的顶级属性立即访问?
MSDN 指出:
请注意,is 运算符仅考虑引用转换、装箱转换和拆箱转换。 is 运算符不考虑其他转换,例如用户定义的转换。
对我来说,考虑装箱和未装箱转换的能力似乎意味着某种内省。
A colleague asked me an interesting question today - is the C# keyword/operator "is" considered reflection?
object tmp = "a string";
if(tmp is String)
{
}
How is this operator implemented behind the scenes? Does it require reflection or introspection? Or because of the strongly typed nature of the language, is the Type of the object immediately accessable as a top-level attribute of the object in memory?
MSDN states that:
Note that the is operator only considers reference conversions, boxing conversions, and unboxing conversions. Other conversions, such as user-defined conversions, are not considered by the is operator.
The ability to consider boxed and unboxed conversions seems to imply to me some sort of introspection.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
引用 ECMA-335,
is
运算符生成isinst
对象模型 IL 指令(分区 III §4.6),它是基本指令集的一部分,而不是反射库的一部分(分区 IV §5.5) 。编辑:与反射库相比,
is
运算符非常高效。 您可以通过反射更慢地执行基本相同的测试:编辑 2:您对
castclass
和isinst
指令(您现在已编辑的指令)的效率不正确出帖子)。 它们在任何实际的虚拟机实施中都经过高度优化。 涉及的唯一真正的性能问题是castclass
可能会引发异常,您可以通过使用 C#as
运算符和null
测试来避免这种情况>(对于引用类型)或is
运算符后跟强制转换(对于值类型)。Referencing ECMA-335, the
is
operator generates theisinst
object model IL instruction (Partition III §4.6), which is part of the base instruction set as opposed to being part of the Reflection library (Partition IV §5.5).Edit: The
is
operator is extremely efficient compared to the reflection library. You could perform basically the same test much more slowly via reflection:Edit 2: You are not correct about the efficiency of the
castclass
andisinst
instructions (which you've now edited out of the post). They are highly optimized in any practical VM implementation. The only real performance issue involved is the potential forcastclass
to throw an exception, which you avoid by using the C#as
operator and a test fornull
(for reference types) or theis
operator followed by a cast (for value types).is
运算符本质上确定是否可以进行强制转换,但当强制转换不可能时,它不会抛出异常,而是返回false
。 如果您考虑投射反射,那么这也是反射。编辑:
经过一些研究,我发现在 IL 中通过
castclass
指令执行强制转换,而is
运算符映射到isinst
指令。 FxCop 有一个规则,如果您首先使用isinst
然后使用castclass
指令进行不必要的转换。 尽管操作高效,但仍然存在性能成本。The
is
operator essentially determines if a cast is possible, but instead of throwing an exception when the cast is impossible it returnsfalse
. If you consider casting reflection then this is also reflection.EDIT:
After some research I have discovered that a cast is performed in IL på the
castclass
instruction while theis
operator maps to theisinst
instruction. FxCop has a rule that warns you if you are doing unecessary casts by first using theisinst
and then thecastclass
instruction. Even though the operations are efficient they still have a performance cost.其他语言具有足以支持动态转换的运行时信息,但没有什么可以被描述为反射(C++ 是一个明显的例子)。
因此,反射指的是除了发现对象类型之外的附加功能。 例如,“反射”一个物体意味着能够行走其成员。
Other languages have runtime time information sufficient to support dynamic casting, and yet nothing that could be described as reflection (C++ being an obvious example).
So reflection refers to additional capabilities beyond merely discovering the type of an object. To "reflect" on an object implies the ability to walk its members, for example.