带有out参数的Func <T>

blu*_*blu 156 .net c# linq generics func

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

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

// somewhere else
public IList<T> Find(Func<string, int, List<T>> listFunction) { }
Run Code Online (Sandbox Code Playgroud)

Func需要一个类型,因此不会在那里编译,并且调用listFunction需要一个int并且不允许输入.

有没有办法做到这一点?

Meh*_*ari 215

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

delegate V MyDelegate<T,U,V>(T input, out U output);
Run Code Online (Sandbox Code Playgroud)

  • 在C#4(2010)及其后期(当你写下答案时没有发布),可以将`T`标记为逆变,将'V`标记为协变.但是,由于'U`类型的参数(`output`)通过引用***传递***,因此`U`不能标记为共变或逆变,并且必须保持"不变".因此,考虑`public delegate V MyDelegate <in T,U,out V>(T input,out U output);`如果你使用C#4或更高版本. (5认同)

Cha*_*ion 23

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

public class Result
{
     public IList<Foo> List { get; set; }
     public Int32 Count { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 因为为每个结果“新建”一个“类”对象会产生 GC 税,这对于高频操作来说非常重要(因此请考虑使用“ValueTuple”代替)。 (3认同)

naw*_*fal 13

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)
Run Code Online (Sandbox Code Playgroud)

这样的代表可以有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)
Run Code Online (Sandbox Code Playgroud)

只有两个参数.我们甚至没有碰过ref.对于开发人员来说,这实际上是麻烦和混乱的.

  • 注意,C#函数重载不能区分`delegate TResult Func <T1,T2,TResult>(T1 obj,T2 obj)`和`delegate TResult Func <T1,T2,TResult>(out T1 obj,T2 obj)`.因此除了重载次数之外,符号名称是微软无法添加`Func`的这些重载的另一个原因. (2认同)