【问题标题】:List of Func delegates with varying return types and number of parameters具有不同返回类型和参数数量的 Func 委托列表
【发布时间】:2013-03-23 21:09:11
【问题描述】:

我有一个类需要在构造函数中传递不同数量的 Func 委托。这些委托中的每一个都将指向一个不同的函数,每个函数都有不同的返回类型,并且具有不同数量的参数(双精度型)。然后将相应地调用这些函数中的每一个。

问题 1. 现在,为了让使用这个类的人更容易,我正在考虑允许用户传递一个 List<object> 的 Func 代表。这是否可能,如果可以,我是否能够在将 List<object> 传递给(即构造函数)的方法中确定每个 Func 所需的返回类型和参数数量?

问题 2. 如果上述方法不可行,我是否需要使用返回类型/参数数量的每种不同组合重载构造函数并相应地路由每个 Func -_- ...如果没有,有人可以指出我正确的方向,我觉得我正在以错误的方式接近这个......

注意 - 来自 python 背景,我会做这样的事情(我对 c# 没有经验):

import inspect
def test(x): return x
inspect.getargspec(test)

returns: ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)

非常感谢

【问题讨论】:

  • 您将大量函数传递给一个类的设计很不寻常。您是否考虑过为每个要传递的函数定义一个具有一个虚拟方法的类并让用户覆盖这些?
  • 你:我能否确定每个 Func 所需的返回类型和参数数量 除了使用List<object>,你可以使用List<Delegate>,因为所有@987654326 @ 类型派生自 System.Delegate。那么如果dList<Delegate> 的一个元素,您可以使用d.Method.ReturnTyped.Method.GetParameters() 来获取您要求的信息。您可以使用d.DynamicInvoke 调用委托。

标签: c# delegates


【解决方案1】:

问题 1. 现在,为了让那些使用这个类的人更容易,我正在考虑允许用户传递一个 Func 委托列表。这是否可能,如果可以,我是否能够确定传递给 List 的方法(即构造函数)中每个 Func 所需的返回类型和参数数量?

不是真的。您可以允许 List<Delegate>(或其他元素类型为 Delegate 的集合),但不允许 Func 特定的集合,原因有两个:

  • Func 实际上是一个 family 类型,具有不同数量的泛型类型参数。就 CLR 而言,这些类型是完全独立的; Func<TResult>Func<T, TResult>Action<T>EventHandler 一样不同。

  • 即使您只处理相同泛型委托的多个值,它们可能具有不同类型参数的事实意味着它们对于 CLR 来说是不同的类型;没有办法说List<Func<>> 是“具有可能变化的类型参数的函数列表”。同样,CLR 将它们视为单独的类型 - 尽管这一次至少有一个具有通用泛型类型定义。

问题 2. 如果上述方法不可行,我是否需要使用返回类型/参数数量的每种不同组合重载构造函数并相应地路由每个 Func

嗯,有几个选择:

  • 将所有参数设为可选,给每个参数一个默认值null,然后在调用构造函数时使用命名参数:

     var foo = new Foo(clickHandler: () => ...,
                       keyHandler: key => ...);
    
  • 创建一个构建器,以便可以将各种函数设置为属性 - 这与对象初始化器语法非常有效:

     var foo = new Foo.Builder {
                   ClickHandler = () => ...,
                   KeyHandler = () => ...
               }.Build();
    

当然,后两种解决方案都取决于您是否真的有特定的命名目的。

如果您可以更清楚地了解您想要实现的目标,这将有所帮助 - 正如 dtb 所说,多态性可能更适合这里。您可以创建一个具有虚拟方法的无操作实现的抽象类,并且实现可以选择要覆盖的那些。

【讨论】:

  • 谢谢乔恩。我想我会沿着使参数可选的路线走下去。为了清楚起见-我可以将代表装箱到对象列表中,然后传递给构造函数吗?如果我能做到这一点,c# 中是否有与 python inspect.getargspec 方法类似的功能?再次感谢您的帮助。
  • @Sherlock:不会涉及任何拳击;委托已经是引用类型。您可以将它们全部转换为Delegate,但它可能会很混乱。我怀疑你仍然在想太多关于你会在 Python 中做什么 - 惯用的 C# 通常是非常不同的,任何给定问题的最简洁的解决方案在 C# 中很可能与 Python 中相同问题的最简洁的解决方案完全不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多