C# "is"运算符 - 那是反射吗?

标签 c# .net reflection introspection typing

今天一位同事问了我一个有趣的问题 - C# 关键字/运算符“是否”被视为反射?

object tmp = "a string";
if(tmp is String)
{
}

这个操作符是如何在幕后实现的?是否需要反射(reflection)或反省?或者由于语言的强类型特性,对象的类型是否可以作为内存中对象的顶级属性立即访问?

MSDN指出:

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.

考虑装箱和未装箱转换的能力对我来说似乎意味着某种内省(introspection)。

最佳答案

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

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

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

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

关于C# "is"运算符 - 那是反射吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1134004/

相关文章:

C# Windows 窗体 FormClosing 事件

c# - 迭代时如何跳出 IAsyncEnumerable?

c# - Attribute.GetCustomAttributes 和 MemberInfo.GetCustomAttributes 可以互换吗?

java - 将 HashMap 转换为给定 javabean 类的 JavaBean 实例

c# - ApplicationSignInManager 是否保留成功登录的列表?

c# - .NET 中的 JObject.SelectToken 等效项

C# ToTitleCase 和文本格式的日期/时间

.net - 从 .Net 中的字典对象获取唯一的配对

c# - 在 C# 中使用 LINQ 的条件过滤器

scala - 如何显示所有类型的对象(Scala中)的?