簡體   English   中英

如何在 C# 中使用私有構造函數實例化 object?

[英]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(...));

我的示例不是很好的代碼,因為它沒有演示設置命令參數屬性或重用參數/命令,但您明白了。

如果您的Typeprivateinternal ,它也會有所幫助:

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM