2010-07-23 59 views
0

我想要做的是这样的。从字符串动态创建对象到派生类型

我有一个继承树看起来像这样

BaseType 
BaseType : DerType1 
BaseType : DerType2 
BaseType : DerType3 

所以首先我声明BaseType类型的变量使用

BaseType b; 

任何派生类型的可以读作为字符串

所以我有一个实例创建者的东西像

object o = Activator.CreateInstance(Type.GetType(readValue)); 

什么,我那么想要做的就是这个新对象分配给B

喜欢的东西

b = o //Doesn't work obviously because of casting rules 
b= (DerType1)o; //works 

,但我无法弄清楚如何动态地重新输入打算投

b = (o.GetType())o; //what i want but can't be done like this 

也许有一种使用泛型的技巧我没有想过?

我发现了一篇文章谈论与泛型

public T GetInstance<T>(string type) where T: new() 
     { 
      return (T)Activator.CreateInstance(Type.GetType(typeName)); 
     } 

做这样的东西,但在我看来,我仍然需要在调用静态引用类型名称这种方法

b = GetInstance<DerType1>("DerType1") 
b = GetInstance<DerType2>("DerType2") 
b = GetInstance<DerType3>("DerType3") 

感谢您的想法。

也许我应该采取一种全新的,更好的方法? 此外也许我只是不重视作为

b = (BaseType)Activator.CreateInstance(Type.GetType(typeName)); 

似乎是有帮助的

+2

您可以直接转换为BaseType;您不需要转换为最常用的派生类型,以便存储到BaseType变量。 – 2010-07-23 18:14:25

+1

因为你所有的类都是从BaseType派生的,并且你的变量是这个类型,所以这个类型的转换应该使用这个类型来完成,而不是使用特定的子类'b =(BaseType)o;'。我错过了什么吗? – CriGoT 2010-07-23 18:18:13

回答

1

为什么不干脆宣布:

object o; 

BaseType o; 

然后,你可以这样做:

BaseType o = Activator.CreateInstance(Type.GetType(readValue)) as BaseType; 
+0

这正是我偶然发现的。在创建我的信息期间。 – Beta033 2010-07-23 18:28:13

2

不要强制转换为派生类型,如果你不这样做与他们任何事情。只投给基类型:

BaseType b = (BaseType)Activator.CreateInstance(Type.GetType(readValue)); 

你只需要投比BaseType更具体的一个类型,如果你要编写依赖于该派生类型的成员代码。如果要以多态方式处理所有派生类型,只需转换为基本类型。

类型层次结构内施放不改变对象的引用你的类型......他们只是执行快速运行时检查(以确保引用实际上该类型),然后重新诠释参考。

0

我会建议为你的类型创建一个工厂(铸造一切BaseType,因为这是你真正要使用的类型):

public static BaseTypeFactory 
{ 
    public enum Types { DerType1, DerType2, DerType3 } 

    public static BaseType CreateInstance(Types type) 
    { 
     switch(type) 
     { 
      case Types.DerType1: 
       return (BaseType) Activator. 
        CreateInstance(Type.GetType("DerType1")); 
      case Types.DerType2: 
       return (BaseType) Activator. 
        CreateInstance(Type.GetType("DerType2")); 
      case Types.DerType3: 
       return (BaseType) Activator. 
        CreateInstance(Type.GetType("DerType3")); 
      default: 
       thrown new ArgumentException("Invalid Type specified"); 
     } 
    } 
} 
+0

这似乎不是很灵活。 – 2010-07-23 18:33:08