41

我绝对记得在某处看到一个使用反射或其他东西的例子。这是与用户无法创建的事情有关SqlParameterCollection(如果我没记错的话)。可惜再也找不到了。

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

4

4 回答 4

75

您可以使用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()
        {
        }
    }
于 2009-04-02T09:27:57.730 回答
53
// 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);
}
于 2009-04-02T09:38:34.100 回答
1

如果该类不是您的类,那么听起来 API 是故意编写的以防止这种情况发生,这意味着您的方法可能不是 API 编写者的意图。查看文档,看看是否有推荐的方法来使用这个类。

如果您确实可以控制该类并希望实现此模式,那么它通常通过类上的静态方法来实现。这也是构成单例模式的一个关键概念。

例如:

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

我的示例不是很好的代码,因为它没有演示设置命令参数属性或重用参数/命令,但您明白了。

于 2009-04-02T09:21:40.630 回答
1

Type如果您的isprivate或,它也会有所帮助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);
    }
于 2016-08-22T10:12:14.513 回答