2011-11-05 55 views
1

我有一个带有2个构造函数的公共类:默认(不带参数),它是内部的,不同的是公共的。 默认构造函数使用一些默认值调用另一个构造函数。如何防止C#编译器删除内部构造函数

我使用反射调用内部构造函数,所以它不会在静态组件中的任何位置使用(仅通过反射)。

当我做了反思电话,我得到:

System.MissingMethodException 
    Message=No parameterless constructor defined for this object. 

我知道两种解决方法的:

  1. 使构造公共(但我不希望这样的用户装配使用它)。
  2. 从一些公共方法调用构造函数(我有很多这样的类,所以我不想写很多这个丑陋的无用代码)。

对这个问题有什么更好的解决办法?

值得一提的是,如果默认的构造函数是公共的,我不会得到这个异常。

谢谢,

波阿斯。

+4

C#编译器不会删除代码。使用ildasm.exe来说服你自己。 –

+1

向我们显示导致此异常的代码。你在反射调用中提供了正确的'BindingFlags'吗? – AakashM

+0

谢谢,我不知道ildasm。我可以在那里找到默认的构造函数,但我仍然得到一个MissingMethodException。如果它是公开的,我不明白。 – brickner

回答

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(类型,TRUE)会调用构造两个如果是公共或私人\内部\保护。

+0

谢谢。确实如此。我有其他这样的类与公共默认构造函数。我试图设置(BindingFlags.NonPublic | BindingFlags.Public),但它只能找到NonPublic的。 – brickner

+1

Activator.CreateInstance(type,true)将调用构造函数,如果它是public或non-public。 –

+0

谢谢,这个作品! – brickner

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)

+0

谢谢。但是,当我使用Activator.CreateInstance(类型,BindingFlags.NonPublic | BindingFlags.Public)时,它只能找到NonPublic,并且找不到具有public类型的公共构造函数。 – brickner

+0

@brickner:我相信你实际上只是调用了错误的Activator.CreateInstance重载,并且它试图将绑定标志作为参数传递。示例... –

+0

Activator.CreateInstance(type,true)起作用。 – brickner

相关问题