is
运算符在DLR方面如何工作?
为了更明确我的问题,请考虑以下签名:
public bool Is<T>(Func<dynamic> getInstance)
{
return getInstance() is T;
}
默认情况下,Is<T>
什么条件才会返回 true
?此外,DLR 是否提供了任何机制来自定义此行为?
is
运算符在DLR方面如何工作?
为了更明确我的问题,请考虑以下签名:
public bool Is<T>(Func<dynamic> getInstance)
{
return getInstance() is T;
}
默认情况下,Is<T>
什么条件才会返回 true
?此外,DLR 是否提供了任何机制来自定义此行为?
dynamic
与object
相同对待,这意味着将使用getInstance
委托结果的运行时类型来执行此检查。使用dynamic
的唯一区别是,在此处不会进行编译时检查,并且将在运行时使用动态绑定来对getInstance
返回的动态对象执行此检查。
默认情况下,Is要满足什么条件才能返回true?
传递的委托需要返回一个在运行时与T
兼容的类型。
此外,DLR是否提供任何机制来自定义此行为?
不提供。这将使用C#类型的标准规则。任何自定义行为都需要编写到逻辑本身中。
typeof(T).GetType().IsInstanceOfType(getInstance())
相同吗? - smartcavemantypeof(T).IsAssignableFrom(getInstance().GetType())
。 - Reed Copseyobject
与使用其他类型没有任何区别。 - jbtule由于is
已经是一个运行时测试,因此不会进行任何额外的运行时绑定,实际上在编译后的IL中也不会有任何差异。
public bool Is<T>(Func<object> getInstance)
{
return getInstance() is T;
}
Is<T>(Func<object> getInstance)
和Is<T>(Func<dynamic> getInstance)
的方法体IL:
.maxstack 2
.locals init (
[0] bool CS$1$0000)
L_0000: nop
L_0001: ldarg.1
L_0002: callvirt instance !0 [mscorlib]System.Func`1<object>::Invoke()
L_0007: isinst !!T
L_000c: ldnull
L_000d: cgt.un
L_000f: stloc.0
L_0010: br.s L_0012
L_0012: ldloc.0
L_0013: ret
所以答案是,is
关键字不受DLR使用的影响,它的工作方式与使用类型object
相同。
is
的行为,那么编译器将生成动态绑定代码,但它没有这样做。我已经在答案中添加了 IL。 - jbtule
public interface INamed { string Name { get; } }
,并在检查getInstance() is INamed
时,当动态对象包含名为“Name”的字符串属性时,我的自定义DynamicMetaObject
实现将返回 true。你有什么建议吗? - smartcaveman