gpt4 book ai didi

c# - 当实现略有不同时如何使用 DuckTyping?

转载 作者:行者123 更新时间:2023-11-30 17:00:53 24 4
gpt4 key购买 nike

我正在 .NET 中制作可移植类库 (PCL),碰巧在尝试抽象任何行为时,我遇到了一个非常常见的烦恼,即 .NET Framework 对其类型和接口(interface)的占有欲很强 。发现一个类型没有实现任何接口(interface)是很常见的,或者当它实现时,接口(interface)是内部的。

当现有类型具有兼容的方法(相同的名称和签名)时,这很容易:我一直在像这样使用 ImpromptuInterface:

nakedInstanceTheDoesNotImplementAnything.ActAs<MyBeautifulInterface>();

我得到了我想要的。透明且方便。

但是,有些方法略有不同怎么办?

  • 不同的名字
  • 调用点不同:一个是属性getter,一个是方法
  • 一些不同的方法,但只需稍作修改即可轻松适应它们。

通常,建议使用纯 OOP 方法,并告知我们创建和适配器。 但是当您必须适应复杂的类型层次结构时,这可能非常乏味和复杂,当您拥有 UIElement、Control、FrameworkElement 等庞大的类时更是如此……

问题是:我能否使 ImpromptuInterface 克服类型中的这些变化以动态创建适配器?

最佳答案

所以 ImpromtuInterface使用 DLR,基本上当您调用 ActLike() 时,它会发出并缓存该接口(interface)的代理,并将其包装在您的对象周围。

public class Proxy:IMyInterface {

dynamic target;

public int Foo(){
return (int)target.Foo()
}
}

因为它是一个动态调用,如果它是并且 IDynamicMetaObjectProvider 最流行的自定义方法是 System.Dynamic.DynamicObject ,那么您实际上并没有在您的目标上使用该方法.

public class RoughDynamicAdapter:DynamicObject{

public override bool TryInvokeMember(InvokeMemberBinder binder,
Object[] args,
out Object result){

if(binder.Name == "Foo"){
result = /* do your own logic */
return true;
}
result = null;
return false;
}
}

但这需要大量工作,因为您必须像处理修改后的调用一样处理未修改的调用。

有几个预制件DynamicObjectImpromptuInterface我已经搬到了一个单独的图书馆 Dynamitey .

特别是一个,BaseForwarder听起来像您想要的,因为无需处理所有逻辑,将消息转发到目标对象已作为基本功能实现。

public class DynamicAdapter:Dynamitey.DynamicObjects.BaseForwarder {

public DynamicAdapter(object target):base(target){
}

public override bool TryInvokeMember(InvokeMemberBinder binder,
Object[] args,
out Object result){
var newName = binder.Name;
if(newName == "Foo"){
result = Dynamic.InvokeMember(CallTarget, "Bar", args)
return true;
}
//else pass them method on as it was called
return base.TryInvokeMember(binder, args, out result)
}
}

然后使用它将是 new DynamicAdapter(myObject).ActLike<IMyInterface>()

关于c# - 当实现略有不同时如何使用 DuckTyping?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21613651/

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