C#“是” 运算符 - 这是反射吗?

发布于 2024-07-27 13:10:52 字数 452 浏览 5 评论 0原文

今天一位同事问了我一个有趣的问题 - 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

殊姿 2024-08-03 13:10:52

引用 ECMA-335is 运算符生成 isinst 对象模型 IL 指令(分区 III §4.6),它是基本指令集的一部分,而不是反射库的一部分(分区 IV §5.5) 。

编辑:与反射库相比,is 运算符非常高效。 您可以通过反射更慢地执行基本相同的测试:

typeof(T).IsAssignableFrom(obj.GetType())

编辑 2:您对 castclassisinst 指令(您现在已编辑的指令)的效率不正确出帖子)。 它们在任何实际的虚拟机实施中都经过高度优化。 涉及的唯一真正的性能问题是 castclass 可能会引发异常,您可以通过使用 C# as 运算符和 null 测试来避免这种情况>(对于引用类型)或 is 运算符后跟强制转换(对于值类型)。

Referencing ECMA-335, the is operator generates the isinst 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:

typeof(T).IsAssignableFrom(obj.GetType())

Edit 2: You are not correct about the efficiency of the castclass and isinst 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 for castclass to throw an exception, which you avoid by using the C# as operator and a test for null (for reference types) or the is operator followed by a cast (for value types).

不疑不惑不回忆 2024-08-03 13:10:52

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 returns false. 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 the is operator maps to the isinst instruction. FxCop has a rule that warns you if you are doing unecessary casts by first using the isinst and then the castclass instruction. Even though the operations are efficient they still have a performance cost.

灯下孤影 2024-08-03 13:10:52

其他语言具有足以支持动态转换的运行时信息,但没有什么可以被描述为反射(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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文