我正在使用Type.GetConstructor(Type.EmptyTypes)
来获取类的默认构造函数。如果类具有没有参数的默认构造函数(class A
),则它可以工作。但是如果一个类的构造函数具有可选的所有参数(class B
),则它不起作用。程序不知道可选参数是什么,因为它只需要默认构造函数。我可以使用哪些语句使其适用于这两种情况?谢谢,感谢任何帮助!
public class A
{
public A() {}
}
public class B
{
public B(int i = 0, string str = "") {}
}
答案 0 :(得分:6)
说我有以下课程:
public class SomeClass
{
public SomeClass()
{
}
public SomeClass(int x)
{
}
public SomeClass(int x = 0, int y = 0)
{
}
}
基本上,您要求的查询将找到与上面的构造函数1和3匹配的构造函数?如果是这样,请使用:
var constuctors = typeof(SomeClass).GetConstructors()
.Where(x => x.GetParameters().Count() == 0
|| x.GetParameters().Count(param => param.GetCustomAttributes(typeof(OptionalAttribute), false).Count() > 0) == x.GetParameters().Count());
令人难以置信的令人讨厌的查询,但它完成的工作仅返回上面的1和3。
答案 1 :(得分:3)
问题是可选参数只不过是编译时的概念。您需要完全指定构造函数。
var ci = typeof(B).GetConstructor(new [] { typeof(int), typeof(string) });
您可以编写一个帮助函数,该函数将使用默认值调用构造函数。我的例子并不像应该的那样强大,但它应该让你开始。
static Func<T> CreateDefaultConstructor<T>(ConstructorInfo ci)
{
var l = new List<object>();
foreach (var p in ci.GetParameters())
{
if (p.IsOptional)
{
l.Add(p.RawDefaultValue);
}
}
return () => (T)ci.Invoke(l.ToArray());
}
答案 2 :(得分:3)
问题是C#编译器产生了这个:
public class B
{
// Methods
public B([Optional, DefaultParameterValue(0)] int i, [Optional, DefaultParameterValue("")] string str)
{
}
}
下面的内容应该有效:
public static class TypeHelper {
public static ConstructorInfo GetDefaultConstructor<TType>() {
var type = typeof(TType);
return type.GetDefaultConstructor();
}
public static ConstructorInfo GetDefaultConstructor(this Type type) {
if(type == null) throw new ArgumentNullException("type");
var constructor = type.GetConstructor(Type.EmptyTypes);
if(constructor == null) {
var ctors =
from ctor in type.GetConstructors()
let prms = ctor.GetParameters()
where prms.All(p=>p.IsOptional)
orderby prms.Length
select ctor;
constructor = ctors.FirstOrDefault();
}
return constructor;
}
}
答案 3 :(得分:2)
问题是,在B的情况下,它没有没有参数的构造函数。
可选参数是一个编译时构造 - 在IL中,它是一个带有2个参数的构造函数(用属性标记)。因此,就Reflection而言,没有默认的构造函数。
答案 4 :(得分:0)
当构造函数或任何其他方法具有可选参数时,它不会导致编译器生成该方法的多个版本。相反,它生成一个具有所有指定参数的方法。默认值在附加到方法签名的属性中编码。这些在呼叫站点使用,使其值可选。
所以这里没有默认构造函数,而是一个带有2个参数的单一构造函数
答案 5 :(得分:0)
要获取具有更多可选参数或完全没有构造函数的参数,请使用:
typeof(myClass)
.GetConstructors()
.OrderBy(x => x.GetParameters().Length - x.GetParameters().Count(p => p.IsOptional))
.FirstOrDefault();