2013-02-26 61 views
0

我想獲得一個派生類成員在基地CLASSE:訪問派生類成員在基地CLASSE

class Program 
{ 
    static void Main(string[] args) 
    { 
     B b = new B(); 
     b.FieldTest = 5; 
     b.MethodeTest(); 

    } 
} 

public class A 
{ 
    public void MethodeTest() 
    { 
     //will return B 
     Type t = this.GetType(); 
     Console.WriteLine(t); 

     var temp = ???.FieldTest; 
     //i want that these return 5 
     Console.WriteLine(temp); 
     Console.ReadLine(); 
    } 
} 

public class B:A 
{ 
    public int FieldTest; 
} 

我不知道這些是可能的,但我希望你有什麼想法解決它。

謝謝

回答

6

那麼你可能動態類型做到這一點:

dynamic dynamicThis = this; 
var temp = dynamicThis.FieldTest; 

...但它是一個非常奇怪的規定。如果this實際上是只是A的一個實例,或者確實是沒有這樣一個成員的不同子類的實例,您會發生什麼?基本上這是一個狡猾的設計。

目前尚不清楚你想要達到的,但你可能想使A與所有子類可以實現一個抽象財產抽象類。 (請注意,您無法將字段摘要...)

如果這樣做沒有幫助,請提供更多關於您爲什麼要嘗試這樣做的詳細信息。

+1

我認爲模板方法是一種更好的選擇。 – 2013-02-26 16:23:22

+0

@FrederikGheysels - 對於一種方法來說,模板模式看起來有點過分。爲什麼不直接做一個覆蓋呢? – 2013-02-26 16:44:25

+0

我發佈了我的解決方案,但我更喜歡你的性能目的 – Said 2013-02-26 16:53:37

1

你不能這樣做你的例子顯示它的方式。基類不知道派生類的實現。

但是,可以做什麼,是限定在基類,其可以在派生類來實現的虛擬方法或屬性,並返回所需的值(模板方法模式):

public class A 
{ 
    protected virtual int FieldTest { get { return 0; } } 

    public void TestMethod() 
    { 
     Console.WriteLine ("FieldTest: " + FieldTest); 
    } 

} 

public class B : A 
{ 
    protected override int FieldTest { get { return 5; } } 
} 

public class C : A 
{ 
    protected override int FieldTest { get { return 10; } } 
} 
+0

爲什麼downvote? – 2013-02-26 16:23:41

+0

因爲答案是錯的。使用接口,抽象實現並獲得重寫方法/結果......還有一種設計模式可以執行類似於「模板方法」的操作(請參閱http://en.wikipedia.org/wiki/Template_method_pattern)。如果您使用具有反射可能性的語言,這也是一種解決方法。 – Beachwalker 2013-02-26 16:23:46

+0

這就是我所做的...查看代碼。 – 2013-02-26 16:24:23

0

使您的方法變爲虛擬,並在派生類中重寫它。你可以調用基類的實現方法,也可以添加特定的派生類新行爲:

public class A 
{ 
    public virtual void MethodeTest() 
    { 
     //will return B 
     Type t = this.GetType(); 
     Console.WriteLine(t); 
     Console.ReadLine(); 
    } 
} 

public class B:A 
{ 
    public int FieldTest; 

    public override void MethodeTest() 
    { 
     base.MethodeTest(); // base class implementation 

     Console.WriteLine(FieldTest); // FieldTest is available here 
     Console.ReadLine(); 
    } 
} 
0

除非每個AFieldTest財產,你不能沒有檢查做到這一點,A是否實際上是爲B

var b = a as B; 
if (b != null) 
{ 
    b.FieldTest; 
} 
1

基類無權訪問派生類的字段。需要這樣做可能是一個應用程序結構錯誤。

0

您不應該從基類訪問派生類成員。相反,您的設計應該允許更多的派生類型提供實現,然後調用基類。或者,如果調用是跨多個派生類型共享的,那麼邏輯應該屬於基礎。

因爲您似乎需要使用單一方法執行調用,所以正常的重寫應該可以工作。一個人爲的例子,

class Animal 
{ 
    public virtual bool Speak() { //return true. Assume all animals make a sound } 
} 

class Dog : Animal 
{ 
    public override bool Speak() { //Bark and return base.Speak() } 
} 

現在,如果狗定義Eat(),動物不應該看執行derived.Eat。相反,Eat應該在動物中定義並由派生類來調用。

0

謝謝你的迴應! 我試過這個解決方案,它工作得很好

public void MethodeTest() 
    { 
     //will return B 
     Type t = this.GetType(); 
     Console.WriteLine(t); 

     foreach (FieldInfo fieldInfo in t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 
     { 
      Console.WriteLine("{0}\t{1}:{2}", fieldInfo.FieldType.Name, fieldInfo.Name, fieldInfo.GetValue(this)); 

     } 

     Console.ReadLine(); 
    } 
相關問題