gpt4 book ai didi

c# - 有什么方法可以动态实现 'is'/'as' 或者至少伪造它?

转载 作者:行者123 更新时间:2023-11-30 22:36:34 25 4
gpt4 key购买 nike

我有一个类型 ConfigValue,它通过 IDynamicMetaObjectProvider 和自定义 DynamicMetaObject 实例的实现公开动态接口(interface)。

当然,可以将此类型的实例视为 native 类型 - 类似于 XML 元素 - 但根据 XML 的内容和内容,它也可以视为任何其他对象类型的实例它构建的对象类型(这是一个由小老我构建的专有 IOC)。

所以

<value>10</value>

可以看作是 ConfigValue,但也可能是 stringshortdouble 等。转换是通过调用语言指定的隐式或显式转换来实现。 XML 变得更加复杂,因为您可以触发构造函数、方法、属性获取等。

当然,为了实现这一点,我已经重写了 DynamicMetaObject 类型的 BindConvert 成员 - 如果 ConfigValue 不支持转换> 运行时对象,然后发生运行时错误(这很好)。

我刚刚开始编写一段代码,如果我可以对目标类型进行安全转换会很棒,但如果这不起作用回退到其他逻辑 - 类似于:

public DesiredType Foo(dynamic d)
{
DesiredType dt = d as dt;
if(dt != null)
return dt;
//TODO: Fallback logic to build dt from d
}

但是,至少 C#(我敢肯定可能是所有动态感知语言)不会为“as”或“is”操作发出任何动态绑定(bind);大概是因为 DynamicMetaObject 没有进行此类测试的方法。因此,类型测试只是对静态类型信息执行,在这种情况下,它总是失败。

因此我不得不依赖于相当丑陋的东西:

public DesiredType Foo(dynamic d)
{
try
{
return (DesiredType)d;
}
catch(Exception)
{
//TODO: fallback logic
}
}

有什么办法可以避免这里的 try/catch/gulp 模式吗!?我能想到的最好的是 DynamicMetaObject 之上的东西;但是必须先查询,然后再查询类型测试;这只会进一步扩展代码!

最佳答案

我认为这是不可能的。

例如,这段代码:

class Program
{
static void Main(string[] args)
{
dynamic d = new object();

var x = (Program)d;
Console.WriteLine(x);

var y = d as Program;
Console.WriteLine(y);

var z = d is Program;
Console.WriteLine(z);
}
}

如果我们使用 Reflector 对其进行反编译,我们会发现强制转换能够被动态类型拦截的唯一原因是 C# 编译器为了支持它做了很多额外的工作:

class Program
{
private static void Main(string[] args)
{
object d = new object();
if (<Main>o__SiteContainer0.<>p__Site1 == null)
{
<Main>o__SiteContainer0.<>p__Site1 = CallSite<Func<CallSite, object, Program>>.Create(Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(Program), typeof(Program)));
}
Console.WriteLine(<Main>o__SiteContainer0.<>p__Site1.Target(<Main>o__SiteContainer0.<>p__Site1, d));

Program y = d as Program;
Console.WriteLine(y);

bool z = d is Program;
Console.WriteLine(z);
}
}

相比之下,asis 调用只是简单地编译为 IL 指令,没有从 C# 编译器中添加魔法。

这也适用于普通的类型转换运算符(operator);使用 as 而不是强制转换不会执行任何转换强制转换,因此永远不会更改基础对象的类型。

关于c# - 有什么方法可以动态实现 'is'/'as' 或者至少伪造它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6924581/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com