【问题标题】:How to create in C# a method taking a method as parameter having an undeterminded numbers of parameters?如何在 C# 中创建一个将方法作为参数的方法,其参数数量不确定?
【发布时间】:2019-11-08 16:21:07
【问题描述】:

我是 C# 新手,有一个问题。我不确定之前是否有人问过这个问题或类似的问题,但是我找不到明确的解决方案。我在 C# 中创建了一个方法,它的参数是一个泛型方法:

public void MyMethod (some_generic_method)

“some_generic_method”可能具有不同数量的具有同质数据类型的参数。我应该如何创建“MyMethod”的签名?

编辑:我将尝试尽可能清楚地解释为什么需要所要求的解决方案。我正在用 C# 制作一个测试库,该库包含一个类似于“MyMethod”的方法。

想象一下:

  • 用户创建了一个具有多种不同方法的类,
  • 用户正在他/她的 C# 脚本中“使用”我的库,
  • 用户事先知道要能够利用该库,他/她的方法名称必须包含特定的字符串(假设为“test”),
  • 我的库“MyMethod”应该找到那些包含“test”作为其名称一部分的用户定义方法(在我的代码的相应部分中,我使用反射、程序集、类型......和“如果(method.name 包含“test”)”,因此库可以检测这些特定方法并将它们单独传递给它的“MyMethod”),
  • 现在,由于我们不知道那些用户定义的方法签名是什么样的,所以“MyMethod”的参数应该可以处理任何用户定义的方法。这就是为什么在我的问题中我首先提到“some_generic_method”(即“MyMethod”参数)可能具有不同数量的具有同构/异构数据类型的参数。

我希望这个解释能让问题更清楚。

谢谢。

【问题讨论】:

  • 如果你不知道有多少个参数,你想在MyMethod里面怎么调用它?
  • 您能否提供一些具有“具有同质数据类型的不同数量参数”的方法的示例
  • 如果您能给我们一些关于您想要实现的目标的背景信息,而不是您如何尝试实现它,这将会有所帮助。很有可能会有一种更好的方法。
  • 依靠MyMethod 能够处理,好吧,基本上任何事情对我来说似乎都有点臭。几乎是潜在的 XY 情况。您能否举几个具体的例子来说明您正在尝试做什么?
  • 你想把方法解析为参数吗????

标签: c# methods parameters


【解决方案1】:

考虑

据我所知,在不知道其签名的情况下调用方法是不可能的。

在与 Javascript、Python 或 Ruby 不同的 C# 中,签名是静态的,在编译后明确定义,因此是不可变的。

即使在对象上使用反射作为参数,管理具有未知类型未知参数的这种未知方法的参数也会遇到同样的问题。

C# 是一种强类型语言,一种编译语言,甚至使用动态。

C# 泛型并不意味着不知道类型和签名,相反,它们不是 C++ 模板,即使它们是祖先。

使用params 作为参数

https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/params

public delegate void ParameterizedActionWithParams(params object[] parameters);

public void MyAction(ParameterizedActionWithParams action, params object[] parameters)
{
  if ( action != null )
    action(parameters);
  else
    ManageArgumentNullException();
}

使用对象列表

public delegate void ParameterizedActionWithList(List<object> parameters);

public void MyAction(ParameterizedActionWithList action, List<object> parameters)
{
  if ( action != null )
    action(parameters);
  else
    ManageArgumentNullException();
}

限制

你不能有强类型参数。

如果你也需要函数,如果返回的参数可以变化,你只能这样做:

public delegate object ParameterizedFuncWithParams(params object[] parameters);

public delegate object ParameterizedFuncWithList(List<object> parameters);

所以你需要创建这些变体:

public object MyFunc(ParameterizedFuncWithParams func, params object[] parameters)
{
  if ( func != null )
    return func(parameters);
  else
    ManageArgumentNullException();
}

public object MyFunc(ParameterizedFuncWithList func, List<object> parameters)
{
  if ( func != null )
    return func(parameters);
  else
    ManageArgumentNullException();
}

【讨论】:

    【解决方案2】:

    “some_generic_method”可能具有不同数量的具有同质数据类型的参数。

    “同质数据类型”限制有很大帮助。我们可以使用单个类型参数定义我们的新方法:

    public void MyMethod<T>(...)
    

    不幸的是,我们无法通过单一方法完全做到这一点。我们需要为每个支持的类型参数数量进行重载:

    public void MyMethod<T>(Func<T> arg) { ... }
    public void MyMethod<T>(Func<T,T> arg) { ... }
    public void MyMethod<T>(Func<T,T,T> arg) { ... } 
    // etc
    

    如果您查看框架源代码,这就是平台设计者自己必须为委托、元组和参数参数等做的事情。

    但我想知道您是否可以调整以执行以下操作之一:

    public void MyMethod<T>(Func<IEnumerable<T>,T> arg) { ... }
    public void MyMethod<T>(Func<T[],T> arg) { ... } 
    

    【讨论】:

      猜你喜欢
      • 2012-03-06
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 2017-10-12
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多