【问题标题】:Create a C# Func<> type alias创建 C# Func<> 类型别名
【发布时间】:2017-12-20 01:03:41
【问题描述】:

我正在开发一个库,该库有多个地方,用户可以在其中注入 lambda 函数来自定义复杂的后台进程。他们基本上是对图书馆的工作方式进行了一些小的修改。该库正在处理在编译或运行时构建的动态类型,因此没有可以添加抽象或虚拟成员的具体类。该库可以处理数十种客户端定义的配置,其中包含少量到大量的 lambda 自定义(每个自定义都附加到客户端正在构建的动态定义结构之一,并传递给库)。

lambda 函数的签名可能有点复杂,如下所示:

Func<SourceList, PredList, Dictionaries, object>

现在,我发现自己正在做的是在公共和私有接口和变量中重复这个复杂的 Func。比如:

private readonly IList<Func<SourceList, PredList, Dictionaries, object>> _processFunctions
            = new List<Func<SourceList, PredList, Dictionaries, object>>();

public void AddProcessFunction(Func<SourceList, PredList, Dictionaries, object> processFunction)
{
    _processFunctions.Add(processFunction);
}

用户会这样做:

someObject.AddProcessFunction((fromList, predList, dict) => { some process impl }
someOtherObj.AddTargettedProcessFunction("Account", 
                                         (fromList, predList, dict) => { some process impl }
...

如果我必须更改 lambda 的签名,我必须在很多地方进行修改。我希望有一种方法可以定义一种类型,我可以用它来将这个签名存储在一个地方。我确实发现我可以这样做:

using ProcessFunc = System.Func<SourceList, PredList, Dictionaries, object>;

...

private readonly IList<ProcessFunc> _processFunctions = new List<ProcessFunc>();
public void AddProcessFunction(ProcessFunc processFunction)
{
    _processFunctions.Add(processFunction);
}

这可以满足我的要求,但这不是一个很好的解决方案,因为它必须以完全相同的方式在库中的每个 .cs 文件中重复(或者相反,它可能具有完全不同的别名)每个文件,并且仍然可以正常工作,因为这本质上是一个宏替换)。

虽然此方法相当多地清理了代码,并且确实减少了 Func 定义的重复,但完整的 Func 定义仍然在生成的库文档中一遍又一遍地重复,因为完整的定义是在方法签名上重复。这使得文档的读者很难看到哪些函数采用相同的 lambda,因为它们必须比较多个复杂参数,他们永远不会看到 ProcessFuncTypeA 或 ProcessFuncTypeB,因此两个相似但不同的 lambda 很难在视觉上区分(当然我会为不同的签名使用好名字)。

我希望是这样的:

public Function ProcessFunc : Func<SourceList, PredList, Dictionaries, object>;

有没有更好的方法(甚至是另一种方法)在一个地方定义一个 Func 类型并在库中的多个地方重用它?我错过了什么明显的东西吗?

谢谢!

【问题讨论】:

  • 查找delegate :)

标签: c# lambda delegates


【解决方案1】:

C# Reference Source 有时可以提供有关如何实现内部结构以及如何实现类似事物的有用提示。

因此,具有 3 个参数的通用 Func&lt;&gt; 定义为

public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);

因此,您可以将特定的 Func&lt;&gt; 变体定义为

public delegate object ProcessFunc(SourceList arg1, PredList arg2, Dictionaries arg3);

【讨论】:

  • 这正是我所需要的。我知道我忽略了一些东西。谢谢!
猜你喜欢
  • 2013-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
  • 2018-12-16
  • 2010-11-26
  • 1970-01-01
相关资源
最近更新 更多