2016-03-05 88 views
2

我有类:如何通过反射将枚举值传递给类的构造函数?

public enum ProviderType { SqlClient, OracleClient}; 

public class ExternalClass 
{ 
    private string field1; 
    private string field2; 
    private string EnumsDependance; 

    public ExternalClass(string p1, string p2, ProviderType type) 
    { 
     this.field1 = p1; 
     this.field2 = p2; 

     if (type == ProviderType.SqlClient) 
     { 
      this.EnumsDependance = "SQL TYPE"; 
     } 
     else if (type == ProviderType.OracleClient) 
     { 
      this.EnumsDependance = "ORACLE TYPE"; 
     } 
     else 
     { 
      this.EnumsDependance = "NO TYPE"; 
     } 
    } 
} 

在我的计划,我需要创建一个使用反射这个类的一个实例,但必须通过这个类的枚举值的构造,我应该怎么办呢?

该程序位于不同的项目ExternalClass和ProviderType中,并且它必须通过反射来读取。这里是我的草图:

class Program 
{ 
    static void Main(string[] args) 
    { 
     //dynamically load assembly from file ExternalDLL.dll 
     Assembly assembly = Assembly.LoadFile(@"C:\temp\ExternalDLL.dll"); 

     //get type of class ProviderType (enum) from just loaded assembly 
     Type providerType = assembly.GetType("ExternalDLL.ProviderType"); 

     //get type of class ExternalClass from just loaded assembly 
     Type externalClassType = assembly.GetType("ExternalDLL.ExternalClass"); 

     //creating an instance of the class ExternalClass, using reflection 
     //constructor -> ExternalClass(string p1, string p2, ProviderType type) 
     object externalClassInstance = Activator.CreateInstance(externalClassType, new object[]{"param1", 
                           "param2", 
                           "ENUM VALUE" //how should I pass the value? 
                           }); 
    } 
} 
+0

你试过[通过反射获取枚举值](http://stackoverflow.com/a/13378148/996081)? – cubrr

回答

3

解决方案

如果你有一个枚举的Type并希望创建它的实例,从它的名字,通过使用Enum.Parse这样做。通过使用Enum.ToObject

object enumInstance = Enum.Parse(providerType, "SqlClient"); 
object externalClassInstance = Activator.CreateInstance(externalClassType, new object[]{"param1", "param2", enumInstance }); 

如果你想从它的创建一个枚举的例子,你可以这样做,就像这样::然后你就可以像这样创建外部类的实例

object enumInstance = Enum.ToObject(providerType, 0); 
object externalClassInstance = Activator.CreateInstance(externalClassType, new object[]{"param1", "param2", enumInstance }); 

为什么我不能只传递一个整数?

似乎有一些困惑,为什么使用Enum.ToObject是必要的。这是因为Enum不是Int32,也不是从它继承的(它不能 - 在.NET中的所有结构都是sealed。这种混乱来自于事实,你可以投一个整数到一个特定的枚举,并得到它的实例:

ProviderType enumInstance = (ProviderType)0; // Works just fine 

这工作,因为所有枚举具有Int32explicit cast operator。当你这样做时,内部的枚举调用Enum.ToObject。当您调用Activator.CreateInstance时,它不会尝试执行强制转换或转换,并尝试将整数值用作构造函数的参数。由于正在创建的类不包含需要int的构造函数,因此您会得到MissingMethodException

此外,枚举甚至没有int基础是,他们可以是一个bytesbyteshortushortint(默认),uintlong,或ulong。你可以阅读更多关于它here


+0

@GediminasMasaitis它的工作!谢谢 –

+0

@GediminasMasaitis你说得对,我的错。我之前使用'MethodInfo'测试了它,它不需要'Enum.ToObject'。 – Wazner

+1

@Wazner没关系,发生在每个人身上:-)我更新了我的帖子,并解释了为什么会出现这种情况。 –

0

通过值

在C#所有枚举具有一个基础类型,默认情况下,这将是Int32。您可以通过调用Type.GetEnumUnderlyingType来获取枚举的基础类型。

当没有明确定义枚举值的值时,它们将按顺序分配,所以在您的情况下,SqlClient将为0并且OracleClient将为1。

您可以使用Enum.ToObject将基础类型的值转换为枚举类型。

object oracleClient = Enum.ToObject(providerType, 1); 
object inst = Activator.CreateInstance(externalClassType, new object[] { "param1", "param2", oracleClient }); 

按名称

或者,你可以使用Enum.Parse获得由枚举值名称值。

相关问题