2014-03-28 65 views
2

當此功能使用該爲什麼使用Activator.CreateInstance時需要定義無參數構造函數?

Activator.CreateInstance() 

public static List<IType> GetTypeList() 
    { 
     List<IType> types = new List<IType>(); 
     types.AddRange(from assembly in AppDomain.CurrentDomain.GetAssemblies() 
         from t in assembly.GetTypes() 
         where t.IsClass && t.GetInterfaces().Contains(typeof(IType)) 
         select Activator.CreateInstance(t) as IType); 

     return types; 
    } 

如果我的每一個類實現ITYPE如果我定義一個構造函數參數,但並沒有明確寫出默認的構造函數的它抱怨

MissingMethodException未處理 「沒有爲此對象定義無參數構造函數」。

但是當我刪除所有構造函數,它工作正常,沒有錯誤,即使我也沒有明確寫出默認的構造函數。

我認爲默認參數的構造函數總是在那裏,即使你沒有把它定義

回答

7

我認爲默認參數的構造函數總是在那裏,即使你沒有把它定義

不正確。如果您明確定義了任何構造函數,編譯器將不再爲您提供默認的無參數變量。

但是,請注意,您可以實例化一個沒有無參數構造函數的類型。只需使用帶有一組參數的Activator.CreateInstance() overload即可。例如,如果構造函數有兩個int s,而值傳遞42和123:

MyClass obj = (MyClass) Activator.CreateInstance(typeof(MyClass), 42, 123); 

也可以使用反射API直接:

var type = typeof(MyClass); 
var ctor = type.GetConstructor(new Type[] { typeof(int), typeof(int) }); 
MyClass obj = (MyClass) ctor.Invoke(new object[] { 42, 123 }); 

參見Type.GetConstructor()ConstructorInfo.Invoke() MSDN上。

+0

+1。您還可以使用將參數傳遞給構造函數的[CreateInstance](http://msdn.microsoft.com/zh-cn/library/wcxyzt4d%28v=vs.110%29.aspx)。 –

+0

其實你可以做'Activator.CreateInstance(typeof(MyClass),42,123);' – Lee

+0

@AlexeiLevenkov謝謝,只是加上我自己:) – TypeIA

0

如果你希望能夠在不調用構造函數的情況下創建一個對象(比如反序列化時),我會建議你做CLR的工作,並使用FormatterServices.GetUnitializedObject。雖然這滿足不需要對象具有無參數構造函數的要求,但如果不謹慎使用,可能會導致意想不到的副作用。

否則,你需要使用參數構造函數和/或修改代碼來處理參數。

+0

這是一個真是糟糕的主意。 OP幾乎肯定不想這樣做! – TypeIA

+0

給出了選擇,而不是對OP想要做什麼做出假設。正如我所說,它可能會有意想不到的副作用。鑑於代碼示例,我無法看到OP如何能夠適當地調用構造函數,對嗎? – Gent

+0

+1。 @TypeIA - 我認爲這是一種有效的方法,可用於用例和一般有趣的信息。雖然你可能是正確的,OP不需要它,但不清楚實際OP的目標是什麼,如果是定製序列化,這個解決方案可以很好地工作。 MSDN文章中也有足夠的警告。 –

相關問題