[英]How to instantiate an object with a private constructor in C#?
我絕對記得在某處看到一個使用反射或其他東西的例子。 這與用戶無法創建的SqlParameterCollection
有關(如果我沒記錯的話)。 可惜再也找不到了。
有人可以在這里分享這個技巧嗎? 並不是說我認為它是一種有效的開發方法,我只是對這樣做的可能性非常感興趣。
您可以使用Activator.CreateInstance的重載之一來執行此操作: Activator.CreateInstance(Type type, bool nonPublic)
對nonPublic
參數使用true
。 因為true
匹配公共或非公共的默認構造函數; 並且false
僅匹配公共默認構造函數。
例如:
class Program
{
public static void Main(string[] args)
{
Type type=typeof(Foo);
Foo f=(Foo)Activator.CreateInstance(type,true);
}
}
class Foo
{
private Foo()
{
}
}
// the types of the constructor parameters, in order
// use an empty Type[] array if the constructor takes no parameters
Type[] paramTypes = new Type[] { typeof(string), typeof(int) };
// the values of the constructor parameters, in order
// use an empty object[] array if the constructor takes no parameters
object[] paramValues = new object[] { "test", 42 };
TheTypeYouWantToInstantiate instance =
Construct<TheTypeYouWantToInstantiate>(paramTypes, paramValues);
// ...
public static T Construct<T>(Type[] paramTypes, object[] paramValues)
{
Type t = typeof(T);
ConstructorInfo ci = t.GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic,
null, paramTypes, null);
return (T)ci.Invoke(paramValues);
}
這是你要問的問題嗎? Activator.CreateInstance 與私有密封 class
如果 class 不是您的,那么聽起來 API 是故意編寫的以防止這種情況發生,這意味着您的方法可能不是 API 編寫者的意圖。 查看文檔,看看是否有推薦的方法來使用這個 class。
如果您確實可以控制 class 並希望實現此模式,則通常通過 class 上的 static 方法來實現。 這也是構成 Singleton 模式的關鍵概念。
例如:
public PrivateCtorClass
{
private PrivateCtorClass()
{
}
public static PrivateCtorClass Create()
{
return new PrivateCtorClass();
}
}
public SomeOtherClass
{
public void SomeMethod()
{
var privateCtorClass = PrivateCtorClass.Create();
}
}
SqlCommandParameter 就是一個很好的例子。 他們希望你通過調用這樣的東西來創建參數:
var command = IDbConnnection.CreateCommand(...);
command.Parameters.Add(command.CreateParameter(...));
我的示例不是很好的代碼,因為它沒有演示設置命令參數屬性或重用參數/命令,但您明白了。
如果您的Type
是private
或internal
,它也會有所幫助:
public static object CreatePrivateClassInstance(string typeName, object[] parameters)
{
Type type = AppDomain.CurrentDomain.GetAssemblies().
SelectMany(assembly => assembly.GetTypes()).FirstOrDefault(t => t.Name == typeName);
return type.GetConstructors()[0].Invoke(parameters);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.