2014-02-13 58 views
6

我有一個名爲A的抽象類和實現了A的其他類(B,C,D,E ......)。我的派生類保存着不同類型的值。 我也有一個A對象的列表。在基類集合上調用派生方法

abstract class A { } 
    class B : class A 
    { 
     public int val {get;private set;} 
    } 
    class C : class A 
    { 
     public double val {get;private set;} 
    } 
    class D : class A 
    { 
     public string val {get;private set;} 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      List list = new List { new B(), new C(), new D(), new E() }; 
      // ... 

      foreach (A item in list) 
      { 
      Console.WriteLine(String.Format("Value is: {0}", item.val); 
      } 
     } 
    } 

...其中.val不被基類c知道。

我如何獲得這種動態行爲?我不想在long switch/if語句中使用getType。

+1

的事實類從'A'此處無關緊要繼承 - 'A'沒有一個'val',所以子類'VAL沒有關係。你可能只需要使用'object'作爲基類。我想這聽起來像你想使用'動態',如果你使用C#4.0+ – Blorgbeard

+1

@Blorgbeard一個小小的改正。 c#4.0以及.net 4.0 –

回答

2

試試這個:

using System; 
using System.Collections.Generic; 

abstract class A 
{ 
    public abstract dynamic Val { get; set; } 

} 
class B : A 
{ 
    public override dynamic Val { get; set; } 
} 
class C : A 
{ 
    public override dynamic Val { get; set; } 
} 
class D : A 
{ 
    public override dynamic Val { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var list = new List<A> { new B(), new C(), new D() }; 
     // ... 

     foreach (A item in list) 
     { 
      Console.WriteLine(String.Format("Value is: {0}", item.Val)); 
     } 
    } 
} 
+0

我實際上已經忘記了C#中的'dynamic',因爲我從來沒有真正聲明過'dynamic',並且只能在MVC應用程序中使用ViewBag。使用它仍然沒有完全得到OP要求的內容,因爲被重寫的成員不是強類型的,所以使用它們的代碼仍然必須施加結果,並且它們不會限制可以分配給它們的內容。儘管如此,它仍然非常接近。 – jmcilhinney

+0

@jmcilhinney如此使用對象 –

+0

在分配值時,類型在派生類中內部設置。好的是,你可以設置任何類型的值,並且「覆蓋」是可能的,因爲它在基類和派生類中都是相同的類型(動態)。使用重寫的值(get),可以調用具有多態行爲的toString()。 – Omicron

1

如果val不是基類中的一員,那麼你將無法訪問在該類型的引用。這三個派生類可能都有一個名爲val的成員,但它不是同一個成員,所以不能像它那樣對待它。你可以做的是聲明一個泛型類,並使該泛型類型的val屬性,但你不能創建該類型的列表。基本上,你想做的事是不可能的。它不是基於繼承,它不是基於泛型。這聽起來很方便,但它不合邏輯。

3

如果你只是想獲得val的字符串表示我recoment在每個子類

public override string ToString() 
{ 
    return val.ToString(); 
} 

無論哪種方式的重寫的ToString如果你想在子類中的數據,你需要代表它在基類作爲它們都有的共同類型(如對象)。你可以做這樣的

abstract class A 
{ 
    public abstract object GetValue(); 
} 
class B : class A 
{ 
    public int val {get;private set;} 
    public override object GetValue() 
    { 
     return val; 
    } 
} 
1
abstract class A { public string val { get; set; } } 
class B : A 
{ 
    public int val {get;private set;} 
} 
class C : A 
{ 
    public double val {get;private set;} 
} 
class D : A 
{ 
    public string val {get;private set;} 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<object> list = new List<object> { new B(), new C(), new D() }; 
     // ... 

     foreach (A item in list) 
     { 
     Console.WriteLine(String.Format("Value is: {0}", item.val)); 
     } 
    } 
} 
相關問題