2014-10-29 100 views
0

我有一個場景,我希望能夠通過一個方法參數傳遞一個類,並從傳遞的類的實例中獲取類特定的信息。C# - 通過參數傳遞繼承類

例子:

public abstract class Foo { 
    public int x; 
} 

然後

public class Bar : Foo { 
    public int y; 
    public Bar(int y) { 
     this.y = y; 
    } 
} 

我需要什麼,能夠做的就是這樣的事情

public void foobar(Foo f) { 
    int y = f.y; 
} 

這將是這樣調用:

foobar(new Bar(5)); 

這將得到一個特定於類「Bar」的值,該值是Foo類的「Inherits」。

我需要能夠做到這一點沒有typcasting,以便該類將被動態處理。

我知道,我只能說

((Bar)f).y 

然而,問題是我將不得不通過傳遞多個類和靜態類型轉換將擊敗目的。

+0

爲什麼沒有定義那麼在Foo中呢?特別是如果你想要在任何繼承的類中獲得y值。 – juharr 2014-10-29 12:28:58

+0

但它擊敗了面向對象的編程。你不能準備界面,f.e用'y'屬性嗎? – 2014-10-29 12:29:07

+0

查看MSDN的「標識符模式」的鏈接:http://msdn.microsoft.com/de-de/library/dd547125.aspx。它在F#中,而不是C#,但我想這就是你想要實現的。如果您希望可以發佈一些與F#代碼完全相同的C#代碼。 – DMAN 2014-10-29 12:36:15

回答

4

你不應該打破OOP規則檢索值。因此,這裏是解決方案之一:

public interface IBar 
{ 
    int Y { get; } 
} 

public Bar : Foo, IBar { ... } 

public void foobar(IBar f) { 
    int y = f.Y; 
} 

但是,如果你真的想,你可以:

使用動態:

public void foobar(Foo f) 
{ 
    dynamic df = (dynamic)f; 
    int y; 
    try 
    { 
     y = df.y; 
    } 
    catch (RuntimeBinderException) 
    { 
     // case when foo doesn't have a y 
    } 
} 

或反射:

public void foobar(Foo f) 
{ 
    var type = f.GetType(); 
    var field = type.GetFields(BindigFlags.Instance 
           | BindigFlags.Public) 
         .FirstOrDefault(info => info.Name == "y"); 

    if (field == null) 
    { 
     // case when f doesn't have a field 
    } 

    int y = (int)field.GetValue(f); 
} 
+0

接口解決方案無法工作(從我理解的方式),因爲我可以讓類「Foo:Bar」具有變量y,然後是另一個類「Jim:Bar」,它將具有變量q,但不會年。每個類不會有相同的變量,它完全依賴於類。動態關鍵字是我正在尋找的。 – Hobbyist 2014-10-29 12:58:48

0

這可以通過鴨子打字完成,請參考此鏈接:Duck Typing

這可以通過使用動態關鍵字在C#中完成。

0

你試圖用你的設計做什麼是不可能的。想到一種方法 - 在Foo中定義抽象方法,所有繼承的類將覆蓋此方法。此方法將返回y(或來自其他派生類的其他信息)。

public abstract class Foo { 
    public int x; 
    public abstract int GetValue(); 
} 

public class Bar : Foo 
{ 
    private int y; 
    public Bar(int y) 
    { 
    this.y = y; 
    } 
    public override int GetValue() 
    { 
    return y; 
    } 
} 

然後你就可以像這樣

public void foobar(Foo f) { 
    int y = f.GetValue(); 
}