C# Func<T> 带 out 参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1283127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:38:58  来源:igfitidea点击:

Func<T> with out parameter

c#.netlinqgenericsfunc

提问by blu

Can I pass a method with an out parameter as a Func?

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

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

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

Func needs a type so out won't compile there, and calling listFunction requires an int and won't allow an out in.

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

Is there a way to do this?

有没有办法做到这一点?

采纳答案by Mehrdad Afshari

refand outare not part of the type parameter definition so you can't use the built-in Funcdelegate to pass refand outarguments. Of course, you can declare your own delegate if you want:

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

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

回答by ChaosPandion

Why not create a class to encapsulate the results?

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

public class Result
{
     public IList<Foo> List { get; set; }
     public Int32 Count { get; set; }
}

回答by Logan Capaldo

You could wrap it in a lambda/delegate/function/method that exposed the right interface and called FindForBar, but I suspect that FindForBar has count as an out parameter as a reason, so you'd need to be sure throwing that information away was ok/safe/desirable/had the right results (you'd need to be sure of this even if you could just directly pass in FindForBar).

您可以将它包装在一个 lambda/delegate/function/method 中,该方法暴露了正确的接口并称为 FindForBar,但我怀疑 FindForBar 已将其视为 out 参数作为一个原因,因此您需要确保将这些信息扔掉ok/safe/desirable/有正确的结果(即使您可以直接传入 FindForBar,您也需要确定这一点)。

回答by nawfal

The Funcfamily of delegates (or Actionfor that matter) are nothing but simple delegate types declared like

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)

etc. Delegates as such can have out/ref parameters, so in your case its only a matter of custom implementation by yourself as other answers have pointed out. As to why Microsoft did not pack this by default, think of the sheer number of combinations it would require.

等。委托本身可以有 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)

for just two parameters. We have not even touched ref. It would actually be cumbersome and confusing for developers.

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