我需要调用一个接收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都需要是相同的返回类型。
答案 0 :(得分:2)
使用params Expression<Func<object>>[] list
作为参数,而不是T
(请注意,它必须是与params
一起使用的数组)
当然,您需要将结果转换为使用它(除非您的流程可以使用object
...例如在{{1}中执行ToString()
但是,如果根据参数DoSomething
可能会有所不同,您还期望与T
合作吗?
更新:我在this fiddle中做了一个例子,但你可以用这个做的事情非常有限,所以@juharr在评论中说明了它&# 39;如果你解释了你想做什么,那就更好了,所以我们可以提出更实际的选择
此外,如果您不需要表达式(只是回调),则无需传递表达式,只需传递T
(modified 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();