如何通过反射将枚举值传递给类的构造函数
本文关键字:构造函数 值传 何通过 反射 枚举 | 更新日期: 2023-09-27 18:37:28
>我有这样的类:
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?
});
}
}
解决方案
如果您有枚举的Type
并希望从其名称创建其实例,请使用 Enum.Parse
.然后,您可以像这样创建外部类实例:
object enumInstance = Enum.Parse(providerType, "SqlClient");
object externalClassInstance = Activator.CreateInstance(externalClassType, new object[]{"param1", "param2", enumInstance });
如果要从枚举的值创建枚举的实例,可以使用 Enum.ToObject
来实现,如下所示:
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
这是有效的,因为所有枚举都有一个来自 Int32
的显式强制转换运算符。执行此操作时,枚举会在内部调用 Enum.ToObject
。调用 Activator.CreateInstance
时,它不会尝试执行强制转换或转换,而是尝试使用整数值作为构造函数的参数。由于正在创建的类不包含采用int
的构造函数,因此您会得到一个MissingMethodException
。
此外,枚举甚至不必基于int
,它们可以是byte
、sbyte
、short
、ushort
、int
(默认)、uint
、long
或ulong
。您可以在此处阅读有关它的更多信息。
按值
在 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
按枚举值名称获取值。