3

与这个问题类似,我决定看看是否可以将out参数从方法中提取到隐式类型变量中,而无需定义类型。我理想的解决方案如下所示:

var result = LiftOutParam((out p1, out p2, out p3) => {
    return CallMyMethod(i1, i2, out p1, out p2, out p3);
});
var o1 = result.Item1;
var o2 = result.Item2;
var o3 = result.Item3;
var returnValue = result.Item4;

在这种情况下,CallMyMethod有 2 个普通输入变量、3 个out参数和一个返回值。我希望编译器根据传入的委托的语义自动确定o1o2o3和的类型。所以我为输出参数的每个组合创建了一些辅助委托和方法。以下是 3 个参数的示例:returnValueLiftOutParamout

public delegate TReturn Lift<T1, T2, T3, TReturn>(
    out T1 o1, out T2 o2, out T3 o3);

public static Tuple<T1, T2, T3, TReturn> LiftOutParam<T1, T2, T3, TReturn>(
    Lift<T1, T2, T3, TReturn> Lift) {

    T1 o1;
    T2 o2;
    T3 o3;
    TReturn ret = Lift(out o1, out o2, out o3);
    return new Tuple<T1, T2, T3, TReturn>(o1, o2, o3, ret);
}

理论上,编译器应该能够根据委托的语义来确定类型T1、、、T2和。但是,除非我在委托中指定每个参数的类型,否则上述代码不会编译。T3TReturn(out p1, out p2, out p3) => { return CallMyMethod(i1, i2, out p1, out p2, out p3); }out

有没有办法做我想要完成的事情?编写一个通用的辅助方法,可以将out参数的值拉入隐式类型的局部变量,而无需在任何地方显式定义类型?

4

2 回答 2

2

C# 编译器无法通过传入的方法从委托推断泛型类型。更多这里C# 3.0 泛型类型推断 - 将委托作为函数参数传递。它是普通参数还是 ref/out 参数都没有关系。

可能相关:C# 无法推断传递的委托/lambda 的返回类型,如.NET 中的通用方法中所述,无法推断其返回类型。为什么?.

于 2013-01-15T20:14:39.213 回答
2

这里有两个问题:

  1. 当lambda 表达式的一个或多个参数需要reforout修饰符时,语法要求您必须为 lambda 表达式的所有参数指定类型。这是一个语法问题,无论编译器是否能够推断出类型,它都适用。

  2. 必须有一个类型来推断。如果你有方法

    void MyMethod<T>(Action<T> action)
    {
    }
    

    那么你不能这样调用这个方法:MyMethod(t => { });因为在这种情况下没有办法推断出什么T是。T 必须推断为一种特定类型。这可能是一种依赖于另一个泛型参数的类型,该参数在MyMethod被调用时处于范围内。

于 2013-01-15T20:36:28.460 回答