如何在C#中使用私有构造函数实例化对象?

Use*_*ser 30 c# constructor instantiation private-constructor

我绝对记得在某个地方看到一个使用反射或其他东西这样做的例子.这与SqlParameterCollection用户无法创造的事情有关(如果我没有记错的话).不幸的是再也找不到了.

有人可以在这里分享这个技巧吗?并不是说我认为它是一种有效的开发方法,我只是对这样做的可能性非常感兴趣.

Sea*_*ean 62

您可以使用Activator.CreateInstance的重载之一来执行此操作:Activator.CreateInstance(Type type, bool nonPublic)

使用truenonPublic参数.因为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()
        {
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果你调用无参数构造函数,那就没问题.如果你想用params调用私有构造函数,试试这个:`Foo f =(Foo)Activator.CreateInstance(typeof(Foo),BindingFlags.Instance | BindingFlags.NonPublic,null,new object [] {"Param1"}, NULL,NULL);` (7认同)

Luk*_*keH 42

// 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);
}
Run Code Online (Sandbox Code Playgroud)

  • @nrjohnstone 如果您的意思是每个数组元素上的 GetType,则在一般情况下由于空值是不可能的。此外,如果您尝试在这种情况下推断类型,您最终将根据选择的语言实现完整的重载解析,这在 C# 的情况下并非微不足道。 (2认同)