如何通过动态返回传递`Func <t>`列表的`params`?

时间:2016-03-03 19:14:43

标签: c#

我需要调用一个接收list Func<T>的方法,问题是Func的返回对于列表的所有项都不相同。

例如:

//Having the following method:
public void DoSomething(params Expression<Func<T>> list)
{
   //get the property info to get the name and value
   // PropertyInfo p = (propertyExpression.Body as MemberExpression).Member as PropertyInfo;
   //EDIT: Using the answer to change the T to object I needed to get the property info using this: 
   (((UnaryExpression)propertyExpression.Body).Operand as MemberExpression).Member as PropertyInfo;

}

//and the following object
public class Foo
{
    public long Id { get;set; } //LOOK: ITS A LONG PROPERTY
    public string Name { get; set; } // ITS A STRING PROPERTY
}

//I would like to pass these two expressions of DIFFERENT returning types.
Foo f = new Foo();
DoSomething(() => f.Id, () => f.Name); //TWO RETURN TYPES DIFFERENTS.

编译器说这是不可能的,因为方法参数是Generic Type T,所以传递的所有Func都需要是相同的返回类型。

3 个答案:

答案 0 :(得分:2)

使用params Expression<Func<object>>[] list作为参数,而不是T(请注意,它必须是与params一起使用的数组)

当然,您需要将结果转换为使用它(除非您的流程可以使用object ...例如在{{1}中执行ToString()但是,如果根据参数DoSomething可能会有所不同,您还期望与T合作吗?

更新:我在this fiddle中做了一个例子,但你可以用这个做的事情非常有限,所以@juharr在评论中说明了它&# 39;如果你解释了你想做什么,那就更好了,所以我们可以提出更实际的选择

此外,如果您不需要表达式(只是回调),则无需传递表达式,只需传递Tmodified fiddle

答案 1 :(得分:1)

好吧,它不漂亮,但我认为这是它与泛型一起工作的唯一方式。这可能不是一个实际的解决方案:

public void DoSomething<T>(Expression<Func<T>> p)
{

}

public void DoSomething<T1,T2>(Expression<Func<T1>> p1,Expression<Func<T2>> p2)
{

}

public void DoSomething<T1,T2,T3>(Expression<Func<T1>> p1,Expression<Func<T2>> p2,Expression<Func<T3>> p3)
{

}

//etc...

微软用它的Func deligates

做了samae的事情
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, inT7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, out TResult>(
    T1 arg1,
    T2 arg2,
    T3 arg3,
    T4 arg4,
    T5 arg5,
    T6 arg6,
    T7 arg7,
    T8 arg8,
    T9 arg9,
    T10 arg10,
    T11 arg11,
    T12 arg12,
    T13 arg13,
    T14 arg14
) 

答案 2 :(得分:0)

一种可能性是使用流畅的界面而不是列表

public object Command
{
    public void DoSomething()
    {
       //do something, act on values stored in member var;
    }

    public Command AddProp<T>(Expression<Func<T>> propAndValue)
    {
       // Get property and value from expression
       // store in member var
       return this;
    }
}



public class Foo
{
    public long Id { get;set; } //LOOK: ITS A LONG PROPERTY
    public string Name { get; set; } // ITS A STRING PROPERTY
}

// Example usage

Foo f = new Foo();
Command cmd = new Command();

cmd.AddProp(() => f.Id).AddProp(() => f.Name).DoSomething();