2010-01-30 128 views
4

,如果你看看下面的代碼,你會(希望)看看我試圖archieve。基本上,這個代碼:強類型對象

  • 一種通用的存儲媒體項目查詢(它們存儲的類型爲字符串)
  • 如果該項目是SearchCriteria的子類,創建正確的實例
  • 的實例添加到列表(SearchCriteria是超類)

不是很優雅的是,當然,僞開關的情況下,我將不得不更新所有不同的標準,我創建。

所以,我的問題,是有「通用」的方法來創建其使用的字符串爲「源」類型強類型的實例。

我知道我可以使用反射來創建一個實例,但這類型的對象,所以我不能夠將其添加到列表中。哦,只是有一個想法...使用反射創建對象,將其轉換爲超類型(SearchCrit),添加到列表。真正的類型應該仍然是「正確的亞型」我希望......

會嘗試,並更新了這則訊息的結果。任何更好的想法?

克里斯

private IList<SearchCriteria> _searchCriteriaAll; 
    public IList<SearchCriteria> SearchCriteriaAll 
    { 
     get 
     { 
      if (_searchCriteriaAll == null) 
      { 
       _searchCriteriaAll = new List<SearchCriteria>(); 
       var tN = typeof (SearchCriteria).ToString(); 
       foreach (var o in DataStorage.LinkedObjects) 
       { 
        if (tN.StartsWith(o.TypeName)) 
        { 
         if (o.TypeName == typeof(StringSearchCriteria).ToString()) 
          _searchCriteriaAll.Add(new StringSearchCriteria(o)); 
        } 
       } 
      } 
      return _searchCriteriaAll; 
     } 
    } 

編輯:

感謝您的提示, 「正確」 的方式將definitly是工廠模式。我會研究這一點。現在,我使用這個技巧,因爲子類是如此之小,我不想爲每一個工廠。(這個地方是目前唯一一個這樣的「花哨」功能)

private IList<SearchCriteria> _searchCriteriaAll; 
    public IList<SearchCriteria> SearchCriteriaAll 
    { 
     get 
     { 
      if (_searchCriteriaAll == null) 
      { 
       _searchCriteriaAll = new List<SearchCriteria>(); 
       var tN = typeof (SearchCriteria).ToString(); 
       foreach (var o in DataStorage.LinkedObjects) 
       { 
        if (tN.StartsWith(o.TypeName)) 
        { 
         var newO = Activator.CreateInstance(typeof(SearchCriteria).Assembly.FullName, o.TypeName); 
         var newCrit = newO.Unwrap() as SearchCriteria; 
         newCrit.DataStorage = o; 
         _searchCriteriaAll.Add(newCrit); 
        } 
       } 
      } 
      return _searchCriteriaAll; 
     } 
    } 
+0

您沒有FMP中每個類的工廠;你有一個類的家族都有一個工廠,它們都是從一個抽象類型派生的(或者實現一個接口)。不能說我是這種黑客的粉絲;如果我正在維護應用程序,這可能是我首先要做的事情之一,因爲它很難跟蹤和/或調試。 – Aaronaught 2010-01-30 16:48:37

回答

0

這並不完全清楚,我你想達到什麼樣的,但是你可以從這樣的字符串創建類型:

var t = Type.GetType(typeName); 

如果你要檢查它是否是一個正確的子類型,你可以使用IsAssignableFrom方法。

+0

關閉miss :-)不,我有問題,我不知道如何將創建的類型轉換爲返回列表的「真實類型」。但我現在只投射到超類型,在對象上調用函數仍然調用適當的子類型實現.. – 2010-01-30 16:47:46

3

泛型和反射不會成爲好朋友。這裏的一個更簡單的方法是使用非泛型列表界面:

_searchCriteriaAll = new List<SearchCriteria>(); 
IList list = (IList) _searchCriteriaAll; 
... 
Type type = typeof(SearchCriteria).Assembly.GetType(o.TypeName); 
list.Add(Activator.CreateInstance(type)); 

(其中包括o.TypeName命名空間的信息,但不必須裝配合格)

這仍然是運行時類型 - 安全(它會在運行時拋出,如果它是錯誤的),並仍然調整相同的列表。

還請注意,我們只看看裏面Assembly直接通過Assembly.GetType()

相關問題