Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通行证;“参数”;用C作为输入#_C# - Fatal编程技术网

C# 通行证;“参数”;用C作为输入#

C# 通行证;“参数”;用C作为输入#,c#,C#,我有一个函数,看起来像: FuncA(int num, object[] x) 这个函数将要使用的函数是这样写的: FuncB(string s, object x1) FuncB(string s, object x1, object x2) ... 这样函数B就有很多这种形式的重载(实际上是32个),并且是一个给定的函数(我无法访问它) 我想在FuncA中调用FuncB,以便根据输入对象的长度调用正确的重载 有没有一个聪明的方法可以做到这一点 谢谢如果所有FuncB方法都是同一个类的一部

我有一个函数,看起来像:

FuncA(int num, object[] x)
这个函数将要使用的函数是这样写的:

FuncB(string s, object x1)
FuncB(string s, object x1, object x2)
...
这样函数B就有很多这种形式的重载(实际上是32个),并且是一个给定的函数(我无法访问它)

我想在FuncA中调用FuncB,以便根据输入对象的长度调用正确的重载

有没有一个聪明的方法可以做到这一点


谢谢

如果所有
FuncB
方法都是同一个类的一部分,您可以使用重载,它接受一个
Type[]
参数,该参数包含每个参数的确切类型

另一方面,如果每个方法都是从其他地方提供的,则可以将它们存储在数组或字典中(即将“参数数”映射到每个具体方法):


但是,我想知道您的设计是否正确,也许可以以更好的方式实现。

如果所有
FuncB
方法都是同一个类的一部分,您可以使用重载,它接受一个
Type[]
参数,其中包含每个参数的确切类型

另一方面,如果每个方法都是从其他地方提供的,则可以将它们存储在数组或字典中(即将“参数数”映射到每个具体方法):


但是,我想知道您的设计是否正确,也许可以以更好的方式实现。

如果您不介意使用反射,您应该能够使用这种代码:

int FuncA(int num, object[] x)
{
    if (x.Length == 0 || x.Length > 32) throw new ArgumentOutOfRangeException();
    IEnumerable<Type> types = new[] { typeof(string) }.Concat(x.Select(i => typeof(object)));
    MethodInfo info = typeof(FuncBClass).GetMethod("FuncB", types.ToArray());
    IEnumerable<object> parameters = new[] { "Some string" }.Concat(x);
    object result = info.Invoke(null /* ignored if the method is static */, parameters.ToArray());
    return (int)result;
}

如果您不介意使用反射,您应该能够使用这种代码:

int FuncA(int num, object[] x)
{
    if (x.Length == 0 || x.Length > 32) throw new ArgumentOutOfRangeException();
    IEnumerable<Type> types = new[] { typeof(string) }.Concat(x.Select(i => typeof(object)));
    MethodInfo info = typeof(FuncBClass).GetMethod("FuncB", types.ToArray());
    IEnumerable<object> parameters = new[] { "Some string" }.Concat(x);
    object result = info.Invoke(null /* ignored if the method is static */, parameters.ToArray());
    return (int)result;
}

如果这是一个非常孤立的情况,并且您需要它是fastish,我可能会对项目符号进行字节处理,并使用长度开关,而不是使用反射(这将是更简洁的代码,但速度较慢)

所以

虽然很难看,但它会相当快


如果这是库中的常见模式,我可能会考虑使用一些代码生成来创建带有适配器的程序集。或者可能有人已经制作了一个包装器库。

如果这是一个非常孤立的情况,并且您需要它是fastish,我可能会对项目符号进行字节,并使用长度开关,而不是使用反射(这将是更简洁的代码,但速度较慢)

所以

虽然很难看,但它会相当快



如果这是库中的常见模式,我可能会考虑使用一些代码生成来创建带有适配器的程序集。或者可能有人已经创建了一个包装器库。

FuncA的输入可以是:params object[]x。我看不出这有什么帮助。问题是给定的FuncB是以这种奇怪的方式编写的。“最快”的解决方案是使用反射,但如果性能对您很重要,我不建议这样做32相同函数的重载有点过多,特别是因为它们都是相同的类型。有什么特殊的原因不能通过传入数组/列表来实现吗?有32个重载的库的名称是什么?它是mlapp,一个MATLAB dll。如果要从c#运行MATLAB函数,则FuncA的输入可以是:params object[]x。我看不出这有什么帮助。问题是给定的FuncB是以这种奇怪的方式编写的。“最快”的解决方案是使用反射,但如果性能对您很重要,我不建议这样做32相同函数的重载有点过多,特别是因为它们都是相同的类型。有什么特殊的原因不能通过传入数组/列表来实现吗?有32个重载的库的名称是什么?它是mlapp,一个MATLAB dll。如果您想从c#运行MATLAB函数,它们来自同一个类。在这种情况下,即使我得到了正确的重载,我如何以长度相关的方式来称呼它?@AsaridBeck91:嗨,对不起,我之前没有看到你的评论。我可以看到下面的答案显示了如何调用它(即使用一组参数简单地调用
MethodInfo.Invoke
)。如果性能是您关心的问题,您可以使用从该方法信息创建一个普通委托,然后将其放入字典/数组中,以获得每个参数数的快速运行时调度。它们来自同一个类。在这种情况下,即使我得到了正确的重载,我如何以长度相关的方式来称呼它?@AsaridBeck91:嗨,对不起,我之前没有看到你的评论。我可以看到下面的答案显示了如何调用它(即使用一组参数简单地调用
MethodInfo.Invoke
)。如果性能是您关心的问题,您可以使用从该方法信息创建一个普通委托,然后将其放入字典/数组中,以获得每个参数数的快速运行时调度。out参数中的一个参数。要处理这个问题吗?@AsaridBeck91对于out参数,只需在参数数组中的该位置传递null,然后在调用Invoke后从数组中获取该对象。空对象将被值替换,就像使用out参数一样。更多信息请参见此处:@AsaridBeck91我已使用示例更新了我的答案,如果其中一个参数被标记为out,请将其标记为正确,如果这是您问题的解决方案:)out参数中的一个参数。要处理这个问题吗?@AsaridBeck91对于out参数,只需在参数数组中的该位置传递null,然后在调用Invoke后从数组中获取该对象。空对象将被值替换,就像使用out参数一样。更多信息请参见此处:@AsaridBeck91我已经用一个示例更新了我的答案,如果其中一个参数被标记为out,请将其标记为正确,如果这是您问题的解决方案:)这就是我要做的。谢谢。这就是我要做的。谢谢
int FuncA(int num, object[] x)
{
    if (x.Length == 0 || x.Length > 32) throw new ArgumentOutOfRangeException();
    IEnumerable<Type> types = new[] { typeof(string) }.Concat(x.Select(i => typeof(object)));
    MethodInfo info = typeof(int).GetMethod("FuncB", types.ToArray());
    object[] parameters = new[] { "Some string", null /* the out parameter */ }.Concat(x.Skip(1)).ToArray();
    info.Invoke(null /* ignored if the method is static */, parameters);
    return (int)parameters[1]; // Get the out parameter value and cast it
}
switch(num)
{
  case 1: return FuncB(x[0]); 
  case 2: return FuncB(x[0], x[1]); 
  etc