如何使用动态返回传递“Func”列表的“参数”
本文关键字:列表 参数 Func 动态 何使用 返回 | 更新日期: 2023-09-27 18:37:19
我需要调用一个接收Func<T>
list
的方法,问题是列表的所有项目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
,所以所有传递的 Funcs 都需要是相同的返回类型。
使用 params Expression<Func<object>>[] list
作为参数,而不是 T
(请注意,它必须是与 params
一起使用的数组)
当然,您需要转换结果才能使用它(除非您的流程可以使用object
......比如说在DoSomething
里面做一个ToString()
,但是当T
根据参数的不同而不同时,你还期望如何使用T
?
更新:我在这个小提琴中做了一个例子,但你能用它做的事情几乎是有限的,所以正如@juharr评论中所述,如果你解释你想做什么会更好,这样我们就可以建议更实用的替代方案
另外,如果你不需要表达式(只是回调),则不需要传递表达式,只需传递Func
(修改后的小提琴)
好吧
,它并不漂亮,但我认为这是它与泛型一起使用的唯一方法。这可能不是一个实用的解决方案:
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...
Microsoft用它的 Func deliments 做萨米的事情
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
)
一种可能性是使用流畅的接口而不是列表
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();