我试图从反射调用一个方法:
bool ApproveUser(Guid userId)
我正在使用.NET CodeDomCompiler
组件编译程序集,其中包含该方法的类驻留,并且该方法正在被编译为
{Void ApproveUser(System.String, Boolean ByRef, Boolean ByRef)}
这与我所期望的完全不同。这是Guid
参数和返回类型转换成这样的正常行为吗?任何提示都是感激的。谢谢!
Guid request = new Guid("25867C0D-F2FB-6A6A-AC61-FF0000852B58");
object[] args = new object[1] { request };
object classInstance= compilerResults.CompiledAssembly.CreateInstance("FooClass");
MethodInfo methodInfo = classInstance.GetType().GetMethod("ApproveUser");
bool result = (bool)methodInfo.Invoke(classInstance, args);
我希望方法被成功调用,但我收到了以下异常:
An exception of type 'System.Reflection.TargetParameterCountException' occurred in mscorlib.dll but was not handled in user code
Additional information: Parameter count mismatch.
编辑2:我将参数类型从Guid
改为int
:
public bool ApproveUser(int smthg)
编译后的版本现在是
{Void ApproveUser(Int32, Boolean, Boolean ByRef, Boolean ByRef)}
尝试使用GetMethod
:
var methodInfo = classInstance.GetType()
.GetMethod("ApproveUser", new[] { typeof(Guid) });
如果你的方法是私有的,尝试指定BindingFlags
:
var methodInfo = classInstance.GetType()
.GetMethod("ApproveUser", BindingFlags.Instance | BindingFlags.NonPublic);
经过几次测试后,我发现当参数是程序集中的基本类型或结构体时,来自CodeDomProvider
的CompileAssemblyFromDom
方法的行为很奇怪。因此,string
、int
等及其对应的String
、Int32
和可空版本,以及Guid
,在方法中设置为返回类型或参数类型时,会被转换为类似问题中提到的类型。我还用不同的随机类进行了测试,当只使用真实的类时,方法头看起来与原始的相似:
StreamWriter ApproveUser(Stream smthg)
将被编译为
{System.IO.StreamWriter ApproveUser(System.IO.Stream)}
这让我想到,如果我使用object
而不是我正在使用的基本类型,编译结果将令人满意。事实上,
object ApproveUser(object userId)
将被编译为
{System.Object ApproveUser(System.Object)}
,然后可以通过我期望的方式通过反射访问它。显然,这是CodeDomProvider
提供的编译过程中的某种问题。