Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c#中实现代理或装饰器类的最短方法是什么?_C#_.net_Reflection_Proxy_Decorator - Fatal编程技术网

在c#中实现代理或装饰器类的最短方法是什么?

在c#中实现代理或装饰器类的最短方法是什么?,c#,.net,reflection,proxy,decorator,C#,.net,Reflection,Proxy,Decorator,当您有一个实现iVihicle的类car,并且您希望将它封装在一个装饰器中,该装饰器将所有调用转发给car并对它们进行计数时,您将如何做 在Ruby中,我可以构建一个没有任何方法的decorator,并使用method_missing将所有调用转发给car对象 在Java中,我可以构建一个代理对象,通过一个方法运行所有代码,然后转发它 在C#中有类似的事情我可以做吗 更新: 根据回答和我读到的有关System.Reflection.Emit的内容,应该可以编写一个与此类似的方法: Type p

当您有一个实现iVihicle的类car,并且您希望将它封装在一个装饰器中,该装饰器将所有调用转发给car并对它们进行计数时,您将如何做

在Ruby中,我可以构建一个没有任何方法的decorator,并使用method_missing将所有调用转发给car对象

在Java中,我可以构建一个代理对象,通过一个方法运行所有代码,然后转发它

在C#中有类似的事情我可以做吗


更新:

根据回答和我读到的有关System.Reflection.Emit的内容,应该可以编写一个与此类似的方法:

Type proxyBuilder(Type someType, delagate functionToBeApplied, Object forward)
其中,type实现someType的所有接口,执行functiontobeaplied,然后将方法调用转发给对象,同时返回其返回值


有没有这样的库,或者我必须自己编写?

不幸的是,C#中没有mixin支持。因此,您需要实现所有方法,或者使用一些重载reflection.emit来实现。另一种选择是(可选)代理/装饰器基类

abstract class FooBase : IFoo {
   protected FooBase(IFoo next) {this.next = next;}
   private readonly IFoo next;
   public virtual void Bar() { // one of the interface methods
       next.Bar();
   }
   public virtual int Blop() { // one of the interface methods
       return next.Blop();
   }
   // etc
}
然后


注意到使用
FooBase
是严格可选的;任何IFoo都是允许的。

对于代理,如果您想使用标准类型,您可以查看“RealProxy”,但使用起来有点麻烦(它要求您的类继承自MarshalByRefObject)

公共类TestProxy:RealProxy其中T:class
{
公共T实例{get{return(T)GetTransparentProxy();}
私有只读MarshalByRefObject重新对象;
私有只读字符串uri;
publictestproxy():基(typeof(T))
{
REOBJECT=(MarshallByRefObject)Activator.CreateInstance(typeof(T));
var objRef=RemotingServices.Marshal(重新对象);
uri=objRef.uri;
}
//你可以在MSDN上找到更多关于在这里可以做什么的信息。
公共覆盖IMessage调用(IMessage消息)
{
Console.WriteLine(“Invoke!”);
message.Properties[“uu Uri”]=Uri;
返回ChannelServices.SyncDispatchMessage(消息);
}
}
或者你可以从Castle得到“DynamicProxy”。。根据我的经验,它的效果要好一点

但是,如果您使用其中的一个,您不一定会获得很好的性能,我主要是在一开始可能很慢的呼叫中使用它们。。但是如果你愿意,你可以试试


Marc的解决方案会有更好的性能。

请用两个字解释一下,“使用
FooBase
是严格可选的”是什么意思?它是“any
IFoo
被允许”的谓词吗?分号使我可以单独阅读语句,并且参数可以自行添加混淆。尽管有cpt。明显的耳语:“这只是意味着,
FooBase
可能会被任何其他
IFoo
取代,以
FooBase
的方式实现
IFoo
”,如果这么简单,我会感到失望。不是对好的答案感到失望,而是对我的偏执狂感到失望。抱歉“冗长”(现在我需要找到成语,对应这种现象)我认为这是你令人失望的答案;代码应仅依赖于
IFoo
FooBase
只是为选择实现
IFoo
的代码提供了方便。谢谢!如果你有时间,请再回答两个问题:1)这个话题已经有6年了,从那以后看起来没有什么变化,解决问题的方法还是一样的?(从没想到我会错过C++,但是它有<代码> ->代码>重载)2)我是否错了:你是说,从抽象类继承是坏的做法吗?我自己认为它们是默认实现的接口,它们非常方便。显然,可以将
SomeFoo
实例称为
IFoo
。(同时,ms实现了扩展方法的多态性…)
class SomeFoo : FooBase {
   public SomeFoo(IFoo next) : base(next) {}
   public override void Bar() {...}
}
public class TestProxy<T> : RealProxy where T : class
{
    public T Instance { get { return (T)GetTransparentProxy(); } }
    private readonly MarshalByRefObject refObject;
    private readonly string uri;

    public TestProxy() : base(typeof(T))
    {
        refObject = (MarshalByRefObject)Activator.CreateInstance(typeof(T));
        var objRef = RemotingServices.Marshal(refObject);
        uri = objRef.URI;
    }

    // You can find more info on what can be done in here off MSDN.
    public override IMessage Invoke(IMessage message)
    {
        Console.WriteLine("Invoke!");
        message.Properties["__Uri"] = uri;
        return ChannelServices.SyncDispatchMessage(message);
    }
}