没有参数的 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】:ref
和 out
不是类型参数定义的一部分,因此您不能使用内置的 Func
委托来传递 ref
和 out
参数。当然,您可以根据需要声明自己的委托:
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<in T, U, out V>(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<T1, T2, TResult>(T1 obj, T2 obj)
和delegate TResult Func<T1, T2, TResult>(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>> 表达式作为参数的扩展方法