使用反射实例化带有内部构造函数的类型

11
我是一名有用的助手,可以为您进行翻译。以下是需要翻译的内容:

我有一个工厂类需要实例化一个未知类。 它使用以下方式:

public class Factory
{
    public void SetFoo(Type f)
    {
        Activator.CreateInstance(f);
    }
}

问题是我希望该构造函数是内部的,但将其标记为内部会导致MissingMethodException错误,但构造函数在同一程序集中。 如果将其设置为公共,则可以正常工作。
我尝试了这里提供的解决方案 如何通过反射创建具有内部构造函数的类的对象实例? 和这里 使用反射在内部类中实例化具有参数的构造函数 这意味着要这样做:
Activator.CreateInstance(f,true)

但是没有成功...

我正在使用NETStandard.Library(1.6.1)和System.Reflection(4.3.0)

更新:

在此更新时提供的答案指引了我正确的方向:

var ctor = f.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);

var instance = (f)ctor[0].Invoke(null);

谢谢大家!


Activator.CreateInstance(f,true) 对于我来说在使用内部构造函数时运行良好。你能提供一个可重现的示例吗? - René Vogt
构造函数是否需要一些参数? - Matias Cicero
“Factory” 类是否定义在与类型 F 不同的程序集中? - Michael
@Matias 没有参数。 - João Sequeira
@Michael,它属于同一个程序集,只是命名空间不同。 - João Sequeira
3个回答

21

绑定标志(BindingFlags):

var ctor = typeof(MyType).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault(c => !c.GetParameters().Any());

var instance = (MyType)ctor.Invoke(new object[0]);

BindingFlags 获取非公共构造函数。具体的构造函数通过指定的参数类型(或者更确切地说是缺少参数)来找到。Invoke 调用构造函数并返回新实例。


.NET Core 没有一个接受两个参数的 GetConstructor 方法。 - Ricardo Peres
这里出现了问题:'GetConstructor' 没有接受 4 个参数的重载。 - João Sequeira

4

首先,您需要找到构造函数:

var ctor = typeof(MyType).GetTypeInfo().GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single(x => /*filter by the parameter types*/);
var instance = ctor.Invoke(parameters) as MyType;

请添加对 System.Reflection 命名空间的引用。

对于 GetInfo().GetConstructors...,我得到的是 'Type info 不包含 GetConstructors() 的定义'。 - João Sequeira
一个示例可以帮助我们理解如何通过参数类型进行筛选。 - undefined
@Grisha:var ctor = typeof(Target).GetTypeInfo().GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single(x => x.GetParameters().Length == 1 && x.GetParameters()[0].ParameterType == typeof(Target)); - undefined

2
你可以通过反射获取构造函数并调用它。
var ctor = typeof(Test)
    .GetConstructors(
        BindingFlags.NonPublic | 
        BindingFlags.Public | 
        BindingFlags.Instance
    )
    .First();
var instance = ctor.Invoke(null) as Test;

你可能想要过滤掉没有参数的构造函数,否则可能会遇到“ArgumentNullExceptions”,即.GetConstructors().First(c=>c.GetParameters().Length==0) - zafar
@zafar,问题中的示例没有无参构造函数。而答案更多是展示如何完成它。 - Maarten

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接