使用运行时确定的types实例化一个对象

我在我想要实例化将在运行时确定的types的对象的情况下。 我也需要执行一个明确的types转换。

像这样的东西:

static void castTest(myEnum val) { //Call a native function that returns a pointer to a structure IntPtr = someNativeFunction(..params..); //determine the type of the structure based on the enum value Type structType = getTypeFromEnum(val); structType myStruct = (structType)Marshal.PtrToStructure(IntPtr, structType); } 

这显然不是有效的代码,但我希望它传达了我正在尝试做的事情的本质。 我实际上正在进行的方法将不得不执行大约35种不同types的编组操作。 我有几个其他的方法需要做类似的一组类似的东西。 所以,我想从这些方法中分离出确定types的逻辑,这样我只需要编写一次,这样方法就可以保持清洁和可读性。

我必须承认在devise上是一个总的新手。 任何人都可以提出一个好的方法来解决这个问 我怀疑可能有一个我不知道的合适的devise模式。

有几种方法可以创build一个特定types的对象,其中一个是:

 // determine type here var type = typeof(MyClass); // create an object of the type var obj = (MyClass)Activator.CreateInstance(type); 

而且你会在obj中得到一个MyClass的实例。

另一种方法是使用reflection:

 // get type information var type = typeof(MyClass); // get public constructors var ctors = type.GetConstructors(BindingFlags.Public); // invoke the first public constructor with no parameters. var obj = ctors[0].Invoke(new object[] { }); 

从ConstructorInfo返回的一个,你可以“用参数调用()”,并返回一个类的实例,就好像你已经使用了一个“新”运算符。

大多可以做你正在描述的东西,但是由于在编译时你不知道types,所以你必须保持实例的松散types。 在你使用它的每个点检查它的types,然后适当地施放它(这对于支持dynamic特性的 c#4.0是不需要的):

 Type type = CustomGetTypeMethod(); var obj = Activator.CreateInstance(type); ... if(obj is MyCustomType) { ((MyCustomType)obj).Property1; } else if (obj is MyOtherCustomType) { ((MyOtherCustomType)obj).Property2; } 

我想你正在寻找Activator.CreateInstance

像其他人所说的那样,使用Activator.CreateInstance创build一个运行时确定Type的实例是很容易的。 然而,如你在Marshal.PtrToStructure行的示例中所做的那样,铸造它是不可能的,因为在编译时必须知道types是否需要铸造。 另外请注意, Activator.CreateInstance不能与IntPtr结合使用。

如果你的types有一个通用的基类( Object除外),你可以将它转换为基types并调用函数。 否则,调用函数将只能使用reflection。

所以:

 static void castTest(myEnum val) { //Call a native function that returns a pointer to a structure IntPtr val = someNativeFunction(..params..); //determine the type of the structure based on the enum value Type structType = getTypeFromEnum(val); BaseClass myStruct = (BaseClass)Marshal.PtrToStructure(IntPtr, structType); myStruct.SomeFunctionDeclaredInBaseClass(); } 

要么:

 static void castTest(myEnum val) { //Call a native function that returns a pointer to a structure IntPtr val = someNativeFunction(..params..); //determine the type of the structure based on the enum value Type structType = getTypeFromEnum(val); object myStruct = Marshal.PtrToStructure(IntPtr, structType); MemberInfo[] function = FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance, (MemberFilter)delegate(MemberInfo info, object filter) { return info.Name == filter.ToString(); }, "SomeFunction"); if (mi.Length > 0 && mi[0] is MethodInfo) ((MethodInfo)mi[0]).Invoke(myStruct, ..params..); } 

你可以去dynamic:

 using System; namespace TypeCaster { class Program { internal static void Main(string[] args) { Parent p = new Parent() { name = "I am the parent", type = "TypeCaster.ChildA" }; dynamic a = Convert.ChangeType(new ChildA(p.name), Type.GetType(p.type)); Console.WriteLine(a.Name); p.type = "TypeCaster.ChildB"; dynamic b = Convert.ChangeType(new ChildB(p.name), Type.GetType(p.type)); Console.WriteLine(b.Name); } } internal class Parent { internal string type { get; set; } internal string name { get; set; } internal Parent() { } } internal class ChildA : Parent { internal ChildA(string name) { base.name = name + " in A"; } public string Name { get { return base.name; } } } internal class ChildB : Parent { internal ChildB(string name) { base.name = name + " in B"; } public string Name { get { return base.name; } } } } 
  methodName = NwSheet.Cells[rCnt1, cCnt1 - 2].Value2; Type nameSpace=typeof(ReadExcel); Type metdType = Type.GetType(nameSpace.Namespace + "." + methodName); //ConstructorInfo magicConstructor = metdType.GetConstructor(Type.EmptyTypes); //object magicClassObject = magicConstructor.Invoke(new object[] { }); object magicClassObject = Activator.CreateInstance(metdType); MethodInfo mthInfo = metdType.GetMethod("fn_"+methodName); StaticVariable.dtReadData.Clear(); for (iCnt = cCnt1 + 4; iCnt <= ShtRange.Columns.Count; iCnt++) { temp = NwSheet.Cells[1, iCnt].Value2; StaticVariable.dtReadData.Add(temp.Trim(), Convert.ToString(NwSheet.Cells[rCnt1, iCnt].Value2)); } //if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_AddNum" || Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_SubNum") //{ // //StaticVariable.intParam1 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 4].Value2); // //StaticVariable.intParam2 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 5].Value2); // object[] mParam1 = new object[] { Convert.ToInt32(StaticVariable.dtReadData["InParam1"]), Convert.ToInt32(StaticVariable.dtReadData["InParam2"]) }; // object result = mthInfo.Invoke(this, mParam1); // StaticVariable.intOutParam1 = Convert.ToInt32(result); // NwSheet.Cells[rCnt1, cCnt1 + 2].Value2 = Convert.ToString(StaticVariable.intOutParam1) != "" ? Convert.ToString(StaticVariable.intOutParam1) : String.Empty; //} //else //{ object[] mParam = new object[] { }; mthInfo.Invoke(magicClassObject, mParam);