我在使用带有可选参数的C#4.0时遇到了另一个问题。
如何调用一个不需要任何参数的函数(或者更确切地说是构造函数,我有ConstructorInfo
对象)?
下面是我现在使用的代码:
type.GetParameterlessConstructor()
.Invoke(BindingFlags.OptionalParamBinding |
BindingFlags.InvokeMethod |
BindingFlags.CreateInstance,
null,
new object[0],
CultureInfo.InvariantCulture);
(我刚刚尝试了不同的BindingFlags
)。GetParameterlessConstructor
是我为Type
编写的自定义扩展方法。
6条答案
按热度按时间jqjz2hbq1#
根据MSDN,要使用默认参数,应传递
Type.Missing
。如果你的构造函数有三个可选的参数,那么你将传递一个三元素的对象数组,其中每个元素的值都是
Type.Missing
,而不是传递一个空的对象数组。7gcisfzg2#
可选参数由普通属性表示,并由编译器处理。
它们对IL没有任何影响(除了元数据标志),并且反射不直接支持它们(
IsOptional
和DefaultValue
属性除外)。如果你想在反射中使用可选参数,你需要手动传递它们的默认值。
gblwokeq3#
我只是添加一些代码...因为。我同意,代码并不令人愉快,但它相当直接。希望这能帮助那些无意中遇到这个问题的人。它经过测试,尽管可能不如您在生产环境中所希望的那样好:
正在使用参数args调用对象obj上的方法methodName:
下面是函数ArgumentListMatches,它基本上取代了GetMethod中可能存在的逻辑:
大量的LINQ,这还没有经过性能测试!
而且,这不会处理泛型函数或方法调用。这使得这明显更丑陋(如重复的GetMethod调用)。
qncylg1j4#
当您看到代码被反编译时,所有问题都消失了:
c编号:
特别代表:
正如您所看到的,可选参数是一个真正独立的实体,它用特定的属性装饰,并且在通过反射调用时必须相应地加以考虑,如前所述。
fdbelqdn5#
在开源框架ImpromptuInterface版本4中,你可以使用C# 4.0中的DLR来调用very late bound way中的构造函数,它完全知道带有命名/可选参数的构造函数,这比
Activator.CreateInstance(Type type, params object[] args)
快4倍,而且你不必反映默认值。...
或
8xiog9wr6#
我知道这是一个老的线程,但只是想添加这个。如果你不确定这个方法有多少参数,你可以动态地做这个:
希望这个有用。