2012-10-29 71 views
1

我只是做了一些古怪的使用部分類,我想知道是否有一個已經建立的模式,可能已經完成同樣的事情,使用較少混淆的方法。是否有創建工人類訪問受保護成員的標準模式?

問題:

  • 我有保護成員和設計的派生類中做的工作,他們被調用時的虛方法的基類。

  • 我想將這項工作委託給工作人員名單。

  • 但是我需要工人訪問受保護的成員。

我可能過於複雜的解決方案:

注:我知道這依賴於類是部分 - 我與OK,但如果是沒解決」它會很酷噸需要它...

void Main() 
{ 
    ABase aBase = new ADerived(); 
    aBase.DoWork(); 
} 

public partial class ABase 
{ 
    protected int state1 = 1; 
    protected int state2 = 2; 
    List<ABase> workers; 

    public ABase() 
    { 
     workers = new List<ABase>(); 
     CreateWorkers(workers); 
    } 

    protected virtual void CreateWorkers(List<ABase> workers) 
    { 
    } 

    public ABase(ABase aBase) 
    { 
     this.Target = aBase; 
    } 

    public virtual void DoWork() 
    { 
     foreach (var worker in this.workers) 
     { 
      worker.DoWork(); 
     } 
    } 

    protected ABase Target { get; private set; } 
} 

public partial class ABase 
{ 
    public class Worker1 : ABase 
    { 
     public Worker1(ABase aBase) : base(aBase) { } 

     public override void DoWork() 
     { 
      Console.WriteLine (Target.state1); 
     } 
    } 

    public class Worker2 : ABase 
    { 
     public Worker2(ABase aBase) : base(aBase) { } 

     public override void DoWork() 
     { 
      Console.WriteLine (Target.state2); 
     } 
    } 
} 

public class ADerived : ABase 
{ 
    protected override void CreateWorkers(List<ABase> workers) 
    { 
     workers.Add(new Worker1(this)); 
     workers.Add(new Worker2(this)); 
    } 
} 

輸出:

1 
2 
+0

對我來說看起來不錯。工人與受保護的成員在同一個基類中。 –

+0

我不認爲'ABase'需要是部分的,'Worker1'不需要是嵌套類。另外,我不會有一個從工作人員名單中獲得的工作人員(這基本上就是ABase),但這是一個意見問題。 –

+0

如果工作人員沒有嵌套,那麼通過引用一個ABase實例訪問受保護的成員是不可能的(如果我錯了,我會刪除我的問題,並重新考慮它) –

回答

0

我會改變設計,以便工作人員根本不訪問實例字段。我會有DoWork採取一個參數與他們需要的信息,並讓基類傳遞到DoWork方法的狀態。

public class MyState //TODO give better name 
{ 
    public int State1 { get; set; } 
    public int State2 { get; set; } 
} 

public class ABase 
{ 
    public MyState state = new MyState() 
    { 
     State1 = 1, 
     State2 = 2 
    }; 

    List<Action<MyState>> workers = new List<Action<MyState>>(); 

    public ABase() 
    { 
     CreateWorkers(); 
    } 

    public void DoWork() 
    { 
     foreach (var action in workers) 
     { 
      action(state); 
     } 
    } 

    private void CreateWorkers() 
    { 
     workers.Add(new Worker1().DoWork); 
     workers.Add(Worker2.Process); 
    } 
} 

public class Worker1 
{ 
    public void DoWork(MyState state) 
    { 
     Console.WriteLine(state.State1); 
    } 
} 

public class Worker2 
{ 
    public static void Process(MyState state) 
    { 
     Console.WriteLine(state.State2); 
    } 
} 
+0

謝謝,這是更清潔......這是一個繼承與組合的證明,對嗎? –

+0

@AaronAnodide基本上,是的。 – Servy