2011-01-28 112 views
0

我在此之前看到了此問題的變體,但未找到答案。在未知類型的運行時實例化自定義類

我有一個自定義類:

public class Indicator 
{ 
    public double Value { get; set;} 

    virtual public void Calc(val1, val2) {} 
} 

而且我從中獲得許多類,如:

class calc_sum : Indicator 
{  
    override public void Calc(val1, val2) 
    { 
    Value=val1+val2; 
    } 
} 

最後,我有一個類來保存所有「指標」:

class IndicatorCollection 
{ 
    List<Indicator> _collection = new List<Indicator>(); 

    ...Some other methods here... 
} 

我需要的是在「IndicatorCollection」類中提供一種方法,它接受一個基於字符串的從「Indicator」派生的類的名稱並將其添加到_collection。 即:

IndicatorCollection.AddIndicator("calc_sum"); 

這樣,用戶可以添加在運行時的指標(該IndicatorsCollection被綁定到其顯示每個成員的Value屬性的列表)。

我希望我已經清楚了,並且我正在採取正確的方法。 謝謝大家

更新: 活性劑方法正是我一直在尋找的,所以我會盡量變得更加困難:

添加指標實例後,可以IndicatorCollection展露新屬性是類的Value屬性的快捷方式。

即:

// After adding calc_sum to the collection, The IndicatorCollection class will have the following //property: 
public double calc_sum 
{ 
    get { return _collection.Find(i=>i.name=="calc_sym").First().Value; 
    // The indicator class also has a public member of "name" 
} 
+0

您的代碼將無法編譯爲`override`和`virtual`關鍵字不能先修改器列表上。 – Oded 2011-01-28 10:46:41

+0

我也會根據上面的例子製作`Indicator`和`Calc`方法摘要。 – 2011-01-28 10:48:26

回答

3

如果Indicator類及其後代暴露一個公共的無參數的構造函數,你可以使用Activator.CreateInstance()在運行時動態實例從它的名字類:

public class IndicatorCollection 
{ 
    public void AddIndicator(string className) 
    { 
     _collection.Add((Indicator) 
      Activator.CreateInstance(null, className).Unwrap()); 
    } 

    private List<Indicator> _collection = new List<Indicator>(); 
} 
0

您可以使用激活器類實例化基於類名的對象。假設calc_sum指標在bin目錄(或其他探測路徑)的組件存在,你可以得到它的一個實例:

var myIndicator = Activator.CreateInstance(Type.GetType("calc_sum")) as Indicator; 
0

關於第二個要求(你更新後),爲什麼不使用的Dictionary<string, Inidicator>代替List<indicator>存儲的名字呢?也許你過於複雜了你的要求。

public class IndicatorCollection 
{ 
    var _dictionary = new Dictrionary<string, Indicator>(); 

    public void AddIndicator(string className) 
    { 
     _dictionary.Add(
      className, 
      (Indicator)Activator.CreateInstance(null, className).Unwrap() 
     ); 
    } 
} 

然後......

public double GetValue(string indicatorName) 
{ 
    return _dictionary[indicatorName].Value; 
}