隐式输出参数

时间:2013-01-15 19:54:36

标签: c# generics out implicit-typing

this question类似,我决定看看是否有可能将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参数和一个返回值。我希望编译器根据传递给o1的委托的语义自动确定o2o3returnValueLiftOutParam的类型。所以我为out参数的每个组合创建了一些帮助器委托和方法。以下是3个out参数的示例:

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);
}

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

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

2 个答案:

答案 0 :(得分:2)

C#编译器无法使用传入方法的委托推断泛型类型。更多信息C# 3.0 generic type inference - passing a delegate as a function parameter。它是正常参数还是ref / out参数无关紧要。

可能相关: C#无法推断传递的委托/ lambdas的返回类型,如Generic methods in .NET cannot have their return types inferred. Why?中所述。

答案 1 :(得分:2)

这里有两个问题:

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

  2. 必须有一种类型可以推断。如果你有方法

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

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