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

本文关键字:构造函数 值传 何通过 反射 枚举 | 更新日期: 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,它们可以是bytesbyteshortushortint(默认)、uintlongulong。您可以在此处阅读有关它的更多信息。


按值

在 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 按枚举值名称获取值。