2016-03-05 90 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獲得由枚舉值名稱值。

相關問題