2011-01-14 5 views
5

以下のスニペットは、タイプのコンストラクタとメソッドのリストを私に提供します。デフォルトのコンストラクタが値型に対して表示されないのはなぜですか?

static void ReflectOnType(Type type) 
{ 
    Console.WriteLine(type.FullName); 
    Console.WriteLine("------------"); 
    List<ConstructorInfo> constructors = 
      type.GetConstructors(BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.Default).ToList(); 

    List<MethodInfo> methods = type.GetMethods().ToList(); 

    Type baseType = type.BaseType; 

    while (baseType != null) 
    { 
      constructors.AddRange(baseType.GetConstructors(BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic | 
           BindingFlags.Instance | BindingFlags.Default)); 
      methods.AddRange(baseType.GetMethods()); 
      baseType = baseType.BaseType; 
    } 

    Console.WriteLine("Reflection on {0} type", type.Name); 

    for (int i = 0; i < constructors.Count; i++) 
    { 
     Console.Write("Constructor: {0}.{1}", constructors[i].DeclaringType.Name, constructors[i].Name); 
     Console.Write("("); 
     ParameterInfo[] parameterInfos = constructors[i].GetParameters(); 
     if (parameterInfos.Length > 0) 
     { 
      for (int j = 0; j < parameterInfos.Length; j++) 
      { 
       if (j > 0) 
       { 
        Console.Write(", "); 
       } 
       Console.Write("{0} {1}", parameterInfos[j].ParameterType, parameterInfos[j].Name); 
      } 
     } 
     Console.Write(")"); 

     if (constructors[i].IsSpecialName) 
     { 
      Console.Write(" has 'SpecialName' attribute"); 
     } 
     Console.WriteLine(); 
    } 
    Console.WriteLine(); 

    for (int i = 0; i < methods.Count; i++) 
    { 
     Console.Write("Method: {0}.{1}", methods[i].DeclaringType.Name, methods[i].Name); 
     // Determine whether or not each field is a special name. 
     if (methods[i].IsSpecialName) 
     { 
      Console.Write(" has 'SpecialName' attribute"); 
     } 
     Console.WriteLine(); 
    } 
} 

しかし、このメソッドに 'int'型を渡すと、暗黙のコンストラクタが出力に表示されないのはなぜですか?または、上記のコードを変更して、デフォルトのコンストラクタも一覧表示するにはどうすればよいですか(コード内に何かがない場合に備えて)。

+2

興味深い読み取りがことがありますhttp://msmvps.com/blogs/jon_skeet/archive/2008/12/10/value-types- and-parameterless-constructors.aspx –

答えて

9

C#(およびほとんどのCLI言語) - 構造体にパラメータのないコンストラクタを指定することは禁じられているため、C#(および他のほとんどの.NET言語)で作成された構造体には、 IL。 CLRは常に定義されたルール(基本的にはすべての値を0に相当する値で満たす)を使用して値型を初期化し、C#は唯一のオプションとしてそれを強制します。

デフォルトのパラメータのないコンストラクタはC#で生成された構造体には存在しないため、リフレクションを使用しているときは表示されません。

+0

リード、任意のMSDNがありますドキュメンテーションやこれに関する記事がありますので、私はもっと学ぶことができますか? – Arun

+0

@Arun:http://msdn.microsoft.com/en-us/library/aa288208(VS.71).aspx "構造体には明示的なパラメータなしコンストラクタを含めることはできません。構造体のメンバーは自動的にデフォルト値に初期化されます。 –

+0

@Arun:Current - http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx - "各値型には、その型の既定値を初期化する暗黙の既定コンストラクタがあります。" –

1

これはC#とCLIの仕様の違いです。 C#では、すべての値型に(オーバーライドしない)デフォルトのパラメータなしコンストラクタがあると言いますが、これはCLIでは当てはまりません。

多くの場合、実行時はでなく、が存在する場合でもデフォルトのコンストラクタを実行します(これは、CILをターゲットとするほとんどの言語では書き込めません)。構造体にゼロを埋め込んだ後は何もしません。 Jon Skeetのinteresting articleは、パラメータのないコンストラクタを構造体にハッキングした実験です。コンテキストによっては実行されることもあり、時には実行されないこともあります。

いずれの場合でも、リフレクションAPIが、そのタイプのパラメータのないコンストラクタを表示しない理由は、そうでないためです。

1

あなたはどのコンストラクタがあなたと一緒に行きたい場合は、あなたの価値はありません明示的に定義されたコンストラクタを持つ構造体を入力すると、暗黙のコンストラクタですので、あなたは上記の空のリストを取得します

var consturctorList = type.GetContructors(); 

によってcontructorsのリストを取得することができます利用できない反射でそれを台無しにするために、あなたは、逆シリアル化メソッドを使用することができます

FormatterServices.GetUninitializedObject(Type type) 
関連する問題