下面的代码片段给出了一个类型的构造函数和方法列表。
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'类型传递给this方法时,为什么我在输出中看不到隐式构造函数?或者,如何修改上面的代码以列出默认构造函数(如果我在代码中遗漏了某些内容)。
答案 0 :(得分:9)
在C#(和大多数CLI语言)中 - 禁止在结构上指定无参数构造函数,因此,在C#(以及大多数其他.NET语言)中创建的结构甚至不会在IL中定义无参数构造函数。 CLR总是使用定义的规则初始化值类型(基本上,用等价零填充所有值),C#强制将其作为唯一选项。
由于默认情况下,无参数构造函数在C#生成的结构中不存在,因此在使用反射时不会显示。
答案 1 :(得分:1)
这是C#和CLI规范之间的差异。 C#表示所有值类型都有一个(不可覆盖的)默认无参数构造函数,但CLI不是这种情况。
在许多情况下,运行时不运行默认构造函数,即使它存在(这是合理的,因为大多数目标CIL的语言不允许你写一个);用零填充结构后什么都不做。这是Jon Skeet的一个interesting article实验,它将无参数构造函数入侵到一个结构中 - 它有时会运行,有时则不会运行,具体取决于上下文。
在任何情况下,反射API没有向您显示该类型的无参数构造函数的原因是因为没有。
答案 2 :(得分:1)
如果你想要任何构造函数,你可以通过
获得结构列表var consturctorList = type.GetContructors();
如果你的值键入一个没有明确定义的构造函数的结构,你将得到一个空列表,因为隐式构造函数不能用于反映它,你可以使用反序列化方法
FormatterServices.GetUninitializedObject(Type type)
答案 3 :(得分:-1)
为什么没有为值类型显示默认构造函数?
简而言之,因为值类型的构造函数不存在。
更详细的说明here:
据我所知,没有CLR定义的默认构造函数, 参考类型的默认构造函数由C#编译器生成 本身(或其他语言编译器)。所以CLR没有默认值 引用或值类型的构造函数。
对于参考类型,C#定义了默认的无参数ctor,其中 调用基类ctor。但这就是C#编译器要发出的工作 此默认ctor代码,无CLR。现在对于值类型,这不会发生 (即编译器不会发出默认的ctor)
因此,由于“ int”是Valye Type,因此不存在任何构造函数。