質問

In a similar vein to this question, I decided to see if it was possible to pull out parameters from a method into implicitly-typed variables without having to define the types. My ideal solution would look something like this:

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;

In this case, CallMyMethod has 2 normal input variables, 3 out parameters, and a return value. I want the compiler to automatically determine the types of o1, o2, o3, and returnValue based on the semantics of the delegate passed into LiftOutParam. So I created some helper delegates and methods, for each combination of out parameters. Here's an example for 3 out parameters:

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

In theory, the compiler should be able to determine the types T1, T2, T3, and TReturn based on the semantics of the delegate (out p1, out p2, out p3) => { return CallMyMethod(i1, i2, out p1, out p2, out p3); }. However, the above code doesn't compile unless I specify the types of each of the out parameters in the delegate.

Is there a way to do what I'm trying to accomplish? To write a generic helper method that can pull the values of out parameters into implicitly-typed local variables without having to explicitly define the types anywhere?

役に立ちましたか?

解決

There are two issues here:

  1. When a ref or out modifier is needed for one or more of the parameters of a lambda expression, syntax requires that you must specify the type for all of the parameters of the lambda expression. This is a syntax thing and applies no matter if the compiler would have been able to infer the types or not.

  2. There must be a type to infer. If you have a method

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

    then you can't call this method like this: MyMethod(t => { }); Because in this case there's no way to infer what T is. T must be infered to be one specific type. This could be a type that depends on another generic parameter that is in scope when the MyMethod is called.

他のヒント

C# compiler cannot infer generic types from delegates with method passed in. More here C# 3.0 generic type inference - passing a delegate as a function parameter . It doesn't matter if it is normal parameter or ref/out parameter.

Possibly related: C# cannot infer return types of passed delegates/lambdas as explained in Generic methods in .NET cannot have their return types inferred. Why? .

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top