如何使用自动类型转换展开用于函数调用的对象数组?



我正在寻找一种方法来根据给定的函数签名将参数对象数组转换为正确的参数类型,如以下示例所示:

public class Class {
public enum State { A, B, /* ...*/}
public void GenericFunction(State state, params object[] args) {
switch(state) {
case State.A: Apply(CaseA,args); break;
case State.B: Apply(CaseB,args); break;
/* ... */
}
}
public void CaseA(int i, string s) { /* ... */ }
public void CaseB(double[] ds) { /* ... */ }
public void ExampleInvocation() {
GenericFunction(State.A,10,"abc"); // supposed to call CaseA with arguments 10 and "abc"
GenericFunction(State.B,new double[] { 1.2, 3.5, 7.2}); // supposed to call CaseB
GenericFunction(State.A,6.66); // supposed to throw an exception
}
}

c# 中是否有库或某些功能提供类似于方法Apply的东西?

您可以使用反射来做到这一点。代价是性能,没有编译时检查。

typeof(MyType).GetMethod("add").Invoke(null, new [] {arg1, arg2})

示例取自:如何在 C# 中动态调用函数

为了决定使用哪个函数,我会使用反射GetParameters()检查可用的函数(请参阅 https://learn.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.getparameters(并将结果缓存到字典中。

正如其他人已经提到的:虽然这在特殊情况下可能是一种有效的方式 - 但在大多数情况下,这不是你应该在 C# 中执行此操作的方式。

到目前为止,我最终做了类似的事情

private void Apply(string functionName, object[] args) {
var methodInfo = typeof(Class).GetMethod(functionName, BindingFlags.Instance,
Type.DefaultBinder, args.Select(_ => _.GetType()).ToArray(), null);
if (methodInfo == null) {
// error handling - throw appropriate exception
} else {
methodInfo.Invoke(this, args);
}
}

这需要将Apply(CaseA,args)的原始调用更改为Apply(nameof(CaseA),args)

任何更优雅的解决方案仍然受到欢迎。

最新更新