我有一个带有2个构造函数的公共类:默认(没有参数),它是内部的,而另一个是公共的。 默认构造函数使用一些默认值调用另一个构造函数。
我使用反射调用内部构造函数,因此它不会在程序集中的任何位置静态使用(仅通过反射)。
当我进行反射调用时,我得到了:
System.MissingMethodException
Message=No parameterless constructor defined for this object.
我知道两个解决方法:
这个问题有哪些更好的解决方案?
值得一提的是,如果默认构造函数是public,我不会得到该异常。
谢谢,
波阿斯。
答案 0 :(得分:7)
未删除构造函数,可能在搜索构造函数时应指定标记BindingFlag.NonPublic
。
class xxx
{
private xxx() :
this(10)
{
}
public xxx(int value)
{
Console.WriteLine(value);
}
}
static void Main(string[] args)
{
Activator.CreateInstance(typeof(xxx), true);
Console.ReadLine();
}
Activator.CreateInstance有一个带布尔值的重载,您可以在其中指定是否要调用非公共构造函数。
public static Object CreateInstance(
Type type,
bool nonPublic
)
Activator.CreateInstance(type,true)将调用构造函数,如果它是public或private \ internal \ protected。
答案 1 :(得分:3)
C#编译器不为您删除任何构造函数。在Reflector中打开程序集,我相信你会看到你创建的构造函数。
我认为你用来查找构造函数的反射代码更有可能不包括BindingFlags.NonPublic
。示例代码以显示 的工作方式:
using System;
using System.Reflection;
class Foo
{
internal Foo()
{
Console.WriteLine("Foo constructor");
}
}
class Program
{
static void Main(string[] args)
{
var ctor = typeof(Foo).GetConstructor
(BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Instance,
binder: null,
types: new Type[0],
modifiers: null);
ctor.Invoke(null);
}
}
编辑:要将绑定标志传递给Activator.CreateInstance
,您需要使用不同的重载,如下所示:
Activator.CreateInstance(typeof(Foo),
BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Instance,
binder: null,
args: null,
culture: null);
(或者您可以使用评论中提到的CreateInstance(type, true)
。)