2009-02-03 89 views
7

當你有一輛實現IVehicle的班級車,並且你想將它包裝在一個將所有呼叫轉發給汽車的裝飾器中並對它們進行計數時,你會怎麼做?在c#中實現代理或裝飾類的最簡單方法是什麼?

在Ruby中,我可以在不使用任何方法的情況下構建裝飾器,並使用method_missing將所有調用轉發給汽車對象。

在Java中,我可以構建一個代理對象,該對象通過一種方法運行所有代碼,然後轉發它。

在C#中可以做類似的事嗎?


更新:

基礎上,answeres和閱讀有關System.Reflection.Emit什麼從來就應該是可以寫一個方法類同此

Type proxyBuilder(Type someType, delagate functionToBeApplied, Object forward) 

其中type實現someType的所有接口,執行functionToBeApplied,然後將方法調用轉發給對象,同時返回它的返回值。

有沒有這樣做的lib還是我必須寫我自己的?

回答

4

對於代理,如果你想使用標準類型,你可以看看「RealProxy」,雖然它有點麻煩(並且它需要你的類繼承自MarshalByRefObject)。

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); 
    } 
} 

或者你可以得到從城堡「DynamicProxy」。它工作在我的經驗好一點..

如果使用其中的一個,你會不會neccessarily獲得出色的,雖然,我使用他們主要是在第一時間可能會很慢的電話中。但是如果你願意的話,你可以嘗試一下。

Marc的解決方案將有更好的性能。

2

不幸的是,在C#中沒有mixin支持。所以你需要實現所有的方法,或者使用一些重要的反射。另一種方法是(可選的)代理/裝飾基類...

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 
} 

然後

class SomeFoo : FooBase { 
    public SomeFoo(IFoo next) : base(next) {} 
    public override void Bar() {...} 
} 

注意到使用FooBase的是可選的;任何IFoo都是允許的。

+0

請用幾個字來解釋一下,「FooBase`的使用是嚴格可選的」是什麼意思? 「是否允許任何IFoo」?分號讓我單獨閱讀陳述,並且論證是自足的以增加混淆。儘管cpt。明顯的竊竊私語:「它只是意味着,'FooBase`可能被任何其他`IFoo`替換,以`FooBase`的方式實現`IFoo`」,如果它那麼簡單,我會感到失望。不是對那個好的回答感到失望,而是對我的帕拉諾亞感到失望。對不起「冗長」(現在我需要找到成語,對應這種現象) – 2015-09-08 11:10:54

相關問題