2010-04-15 91 views
5
sTypeName = ... //do some string stuff here to get the name of the type 

/* 
The Assembly.CreateInstance function returns a type 
of System.object. I want to type cast it to 
the type whose name is sTypeName. 

assembly.CreateInstance(sTypeName) 

So, in effect I want to do something like: 

*/ 

assembly.CreateInstance(sTypeName) as Type.GetType(sTypeName); 

我该怎么做?而且,假设这是C#2.0,我该如何在赋值表达式的左侧进行操作。我没有var关键字。从类型名称的字符串表示类型转换为类型

回答

2

通常你让所有的类,你想实例化这个动态的,实现一个通用接口,可以说IMyInterface。您可以从类名字符串像这样创建一个实例:

Assembly asm = Assembly.GetExecutingAssembly(); 
string classname = "MyNamespace.MyClass"; 
Type classtype = asm.GetType(classname); 

// Constructor without parameters 
IMyInterface instance = (IMyInterface)Activator.CreateInstance(classtype); 

// With parameters (eg. first: string, second: int): 
IMyInterface instance = (IMyInterface)Activator.CreateInstance(classtype, 
         new object[]{ 
          (object)"param1", 
          (object)5 
         }); 

即使你没有一个通用的接口,但知道方法的名称(如字符串),你可以调用你这样的方法(很相似属性,事件等):

object instance = Activator.CreateInstance(classtype); 

int result = (int)classtype.GetMethod("TwoTimes").Invoke(instance, 
         new object[] { 15 }); 
// result = 30 

的示例类:

namespace MyNamespace 
{ 
    public class MyClass 
    { 
     public MyClass(string s, int i) { } 

     public int TwoTimes(int i) 
     { 
      return i * 2; 
     } 
    } 
} 
2

不幸的是,.NET没有办法做你想做的事情。

可能的部分解决方案是:

  1. 如果你知道在编译时的类型(不太可能,因为你是在从一个字符串运行时创建它),然后简单地映射到该类型:

    YourType t = (YourType)Activator.CreateInstance(sTypeName); 
    
  2. 如果你知道所有可能的类型将实现一个特定的,通用的接口,那么你可以到该接口来代替:

    IYourInterface i = (IYourInterface)Activator.CreateInstance(sTypeName); 
    

如果你不能做上述任何一个,那么不幸的是,你被困在object和反思。

+0

谢谢,我已经完成(2)并正在寻找选项。 – 2010-04-15 09:30:58

2

在类中定义一个通用的方法,然后你可以施放这样的:

public T Cast<T>(object obj) 
{ 
     return (T) obj; 
} 

string sTypename = "SomeClassName"; 
MethodInfo cast = this.GetType().GetMethod("Cast"); 
MethodInfo genericCast = cast.MakeGenericMethod(new Type[] { Type.GetType(sTypename) }); 
Object castedValue = genericCast.Invoke(this, new object[] { instanceToBeCasted }); 

但后来我想,是什么就是这样铸造的点,如果你不能铸造值存储在一个变量实际的类型,正是因为您在编写代码时不知道实际类型?