2011-08-08 28 views
3

我有一些代理的繼承問題。代理據我所知是一對指針:一個實例和一個方法,事情是這是在創建委託時引用的方法,而不受繼承的影響。所以,這是行不通的:在c中的代表和繼承#

public class BaseObject { 
    public delegate void del(); 

    public BaseObject() { 
    next=Method; 
    } 

    public del next; 
    public void ExecuteNext() { 
    next(); 
    } 

    public virtual void Method() { 
    Debug.Log("BASE"); 
    } 
} 

public class InheritedObject:BaseObject { 
    override public void Method() { 
    Debug.Log("INHERITED"); 
    } 
} 
... 

(new InheritedObject()).ExecuteNext(); 

執行運行基礎方法(),我希望它運行繼承的方法()。我已經發現了一些辦法解決,但效率不高,分散注意力,非常容易出錯,反正這裏的,我想擺脫目前的工作版本:

class BaseObject { 
    public delegate void del(); 

    BaseObject() { 
    next=DoMethod;  /// using DoMethod here 
    } 

    public del next; 
    public void ExecuteNext() { 
    next(); 
    } 


    public void DoMethod() { /// using DoMethod here 
    Method(); 
    } 
    public virtual void Method() { 
    // do base 
    } 
} 

class InheritedObject:BaseObject { 
    override public void Method() { 
    // do inherited 
    } 
} 

... 

(new InheritedObject()).Execute(); 

這DoMethod的形式給出的作品,但問題也不少,

  1. 大量的無用的代碼
  2. 容易出錯在使用該類時 - 容易犯的錯誤obj.next = DoMethod與obj.next =繼承的類時Method
  3. 容易出錯 - 我要記住不繼承DoMethod,以及大量的虛擬和覆蓋。

任何建議我該如何做得更好?也許一些註釋魔術本身就是DoMethod?我已經想到詞典 - 他們不擅長在這裏,他們補充混亂甚至是另一個級別(單聲道,.NET 2,Unity3d框架)

+2

你可以用這種方法背後的原因開始。爲什麼你需要委託人? –

+0

'(new InheritedObject())。Method();'工作。正如丹尼爾所說,爲什麼「代表」? – dlev

+0

這只是一個最小的代碼示例,在實際使用中,這個構造是一個角色遊戲邏輯的多級繼承狀態機。 –

回答

4

您可以用next=()=>Method();取代next=DoMethod;基本上是相同的,但沒有按不要求你在你的課堂上定義一個額外的方法。

+0

謝謝,我不知道這個語言結構。 –

+0

不客氣,但在使用此之前,您可能需要查看一些意見,建議您的初始方法應該可行。 – Bubblewrap

+0

是的,我看到那些,只是恩,跆拳道,我試着沒有效果。也許我在其他地方也有錯誤。 –

4

在你第一示例中,要分配的 結果的Method();到委託,所以自然這意味着, Method方法(啊哈)將在該點被執行以指定價值。忽略 Methodvoid(不會編譯)的事實。

在第二個示例中,您將該方法的引用(不必是實例方法)分配給委託,這允許您在稍後階段執行del

對我來說,以下工作:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var baseClass = new BaseObject(); 
     baseClass.Execute(); 

     var derivedClass = new DerivedObject(); 
     derivedClass.Execute(); 

     Console.ReadKey(); 
    } 
} 

class BaseObject 
{ 
    public delegate void SomethingDelegate(); 
    public SomethingDelegate Delegate; 

    public BaseObject() 
    { 
     Delegate += Something; 
    } 

    public virtual void Something() 
    { 
     Console.WriteLine("Base Class"); 
    } 

    public void Execute() 
    { 
     Delegate(); 
    } 
} 

class DerivedObject : BaseObject 
{ 
    public override void Something() 
    { 
     Console.WriteLine("Derived Class"); 
    } 
} 

在上述例子中,一個事實,即代表指針表示爲指針Something方法(的BaseObject),因爲該方法是虛擬的,則呼叫仍然正確地分派給覆蓋方法SomethingDerivedObject)。

你沒有看到相同的行爲?

+0

但是'Method'的返回類型是'void',所以不能被分配給一個委託。第一個例子根本不編譯。 – Guffa

+0

@Guffa - 他原來的代碼(編輯之前)是'del = Method();',它不會編譯。自那時起他已經更新了他的代碼。 –

3

不,Execute將運行繼承的方法。做一些修正代碼後,我可以測試它:

public class BaseObject { 
    public delegate void del(); 

    public BaseObject() { 
    next = Method; 
    } 

    public del next; 
    public void Execute() { 
    next(); 
    } 

    public virtual void Method() { 
    Console.WriteLine("base"); 
    } 
} 

public class InheritedObject : BaseObject { 

    override public void Method() { 
    Console.WriteLine("inherited"); 
    } 

} 

叫:

(new InheritedObject()).Execute(); 

輸出:

inherited