没有参数的 Func<T>

Posted

技术标签:

【中文标题】没有参数的 Func<T>【英文标题】:Func<T> with out parameter 【发布时间】:2009-08-15 23:45:58 【问题描述】:

我可以将带有 out 参数的方法作为 Func 传递吗?

public IList<Foo> FindForBar(string bar, out int count)  

// somewhere else
public IList<T> Find(Func<string, int, List<T>> listFunction)  

Func 需要一个类型,所以 out 不会在那里编译,调用 listFunction 需要一个 int 并且不允许 out in。

有没有办法做到这一点?

【问题讨论】:

【参考方案1】:

refout 不是类型参数定义的一部分,因此您不能使用内置的 Func 委托来传递 refout 参数。当然,您可以根据需要声明自己的委托:

delegate V MyDelegate<T,U,V>(T input, out U output);

【讨论】:

在 C# 4 (2010) 及更高版本中(在您编写答案时未发布),可以将 T 标记为逆变,将 V 标记为协变。但是,由于U 类型的参数 (output) 通过引用 传递,U 不能标记为协变或逆变,必须保持“不变” .因此,如果您使用 C# 4 或更高版本,请考虑 public delegate V MyDelegate&lt;in T, U, out V&gt;(T input, out U output); 见this example for using ref parameter with in and out parameters。【参考方案2】:

为什么不创建一个类来封装结果?

public class Result

     public IList<Foo> List  get; set; 
     public Int32 Count  get; set; 

【讨论】:

【参考方案3】:

Func 委托家族(或 Action 就此而言)只不过是声明为类似的简单委托类型

//.NET 4 and above
public delegate TResult Func<out TResult>()
public delegate TResult Func<in T, out TResult>(T obj)

//.NET 3.5
public delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2)
public delegate TResult Func<T1, T2, T3, TResult>(T1 obj1, T2 obj2, T3 obj3)

等等。这样的代表可以具有 out/ref 参数,因此在您的情况下,正如其他答案所指出的那样,它只是您自己自定义实现的问题。至于为什么微软默认不打包这个,想想它需要的组合数量。

delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2)
delegate TResult Func<T1, T2, TResult>(out T1 obj1, T2 obj2)
delegate TResult Func<T1, T2, TResult>(T1 obj1, out T2 obj2)
delegate TResult Func<T1, T2, TResult>(out T1 obj1, out T2 obj2)

只有两个参数。我们甚至没有碰过ref。对于开发人员来说,这实际上会很麻烦且令人困惑。

【讨论】:

请注意,C# 函数重载无法区分delegate TResult Func&lt;T1, T2, TResult&gt;(T1 obj, T2 obj)delegate TResult Func&lt;T1, T2, TResult&gt;(out T1 obj, T2 obj)。因此,除了重载符号名称的数量之外,Microsoft 无法添加这些重载 Func 的另一个原因。 有人能给我推荐一篇关于上述代表的 MSDN 文章吗? @SuLlewellyn 我找不到原始的 msdn 文章,但你可以试试:docs.microsoft.com/en-us/dotnet/api/…,docs.microsoft.com/en-us/dotnet/api/…【参考方案4】:

您可以将其包装在暴露正确接口并调用 FindForBar 的 lambda/delegate/function/method 中,但我怀疑 FindForBar 已将其视为 out 参数,因此您需要确保将其抛出信息还可以/安全/可取/有正确的结果(即使您可以直接传入 FindForBar,您也需要确定这一点)。

【讨论】:

以上是关于没有参数的 Func<T>的主要内容,如果未能解决你的问题,请参考以下文章

将 Expression<Func<T, bool>> 作为参数传入的 Moq'ing 方法

接受 Expression<Func<T>> 表达式作为参数的扩展方法

如何调用Func并将其传递给构造函数中具有较少参数的另一个Func?

Action 和 Func

模板类非模板化方法参数

系统自带的委托Action和Func