代码之家  ›  专栏  ›  技术社区  ›  Matt

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

  •  28
  • Matt  · 技术社区  · 15 年前

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

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

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

    MSDN 声明:

    请注意,is运算符只考虑引用转换、装箱转换和取消装箱转换。IS运算符不考虑其他转换,例如用户定义的转换。

    考虑盒装和未盒装转换的能力对我来说似乎意味着某种自省。

    3 回复  |  直到 15 年前
        1
  •  34
  •   Sam Harwell    15 年前

    Referencing ECMA-335 , the is 操作员生成 isinst 对象模型IL指令(第三部分第4.6节),它是基本指令集的一部分,而不是反射库的一部分(第四部分第5.5节)。

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

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

    编辑2:您对 castclass 伊辛 说明(你现在已经从帖子中删掉了)。它们在任何实际的虚拟机实现中都是高度优化的。唯一真正涉及的性能问题是 铸钢类 抛出一个异常,使用c可以避免这种异常# as 操作员和测试 null (用于参考类型)或 运算符,后跟强制转换(对于值类型)。

        2
  •  5
  •   Martin Liversage    15 年前

    这个 is 运算符本质上决定了强制转换是否可能,但当强制转换不可能时,它不会引发异常,而是返回 false . 如果考虑投射反射,那么这也是反射。

    编辑:

    经过一些研究,我发现一个演员表是在IL P_ castclass 指令 操作员映射到 isinst 指令。FXCOP有一个 rule 这会警告您,如果您正在进行不必要的铸造,首先使用 伊辛 然后 铸钢类 指令。即使操作效率很高,它们仍然有性能成本。

        3
  •  1
  •   Daniel Earwicker    15 年前

    其他语言有足够的运行时间信息来支持动态的铸造,但是没有什么可以被描述为反射(C++是一个明显的例子)。

    因此,反射指的是除了发现对象类型之外的其他功能。例如,在一个物体上“反射”意味着它能够行走它的成员。