开发者

Why default constructor does not appear for value types?

The below snippet gives me a list of constructors and methods of a type.

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

But when I pass an ‘int’ type to this method, why don’t I see 开发者_如何学Gothe implicit constructor in the output? Or, how do I modify the above code to list the default constructor as well (in case I’m missing something in my code).


In C# (and most CLI languages) - specifying a parameterless constructor on a struct is forbidden, and as such, a struct created in C# (and most other .NET languages) will not even have a parameterless constructor defined in the IL. The CLR always initializes value types using defined rules (basically, filling all values with zero equivalents), and C# enforces that as the only option.

Since the default, parameterless constructor does not exist in a C# generated struct, it does not display when using reflection.


If you want any constructor to go with you can get the list of contructors by

var consturctorList = type.GetContructors();

If your value type a struct with no explicitly defined constructors, you will get an empty list above since implicit constructor is not available for messing up with it in reflection, you can use deserialization method

FormatterServices.GetUninitializedObject(Type type)


This is a difference between the C# and CLI specifications. C# says that all value-types have a (non-overridable) default parameterless constructor, but this is not the case with the CLI.

In many cases, the run-time will not run the default constructor even if it exists (this is reasonable since most languages that target CIL don't let you write one); doing nothing after filling the struct with zeroes. Here's an interesting article by Jon Skeet that experiments with hacking a parameterless constructor into a struct - it sometimes runs, and sometimes doesn't, depending on context.

In any case, the reason the reflection API doesn't show you such a parameterless constructor on that type is because there isn't one.


Why default constructor does not appear for value types?

In short, because constructor for value types NOT EXIST.

More detailed explanation here:

To my knowledge,there's no default constructor defined by CLR , the default constructor for reference types is generated by C# compiler itself (or other language compilers). So CLR has no default constructor for neither of reference or value types.

For reference types C# defines default parametreless ctor , which call's upon base class ctor. But that's the c# compiler's job to emit this default ctor code, no CLR. Now for valuetype this does not happen (that is no default ctor is emitted by compiler)

So, since "int" is Valye Type, not exist any constructor for it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜