2010-01-30 125 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()

相关问题