Reputation: 2857
I need to call a method that receive a list
of Func<T>
, the problem is that the return of the Func
is not the same for all the items of the list.
For example:
//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.
The compiler says that it's impossible because the method param is a Generic Type
T
, so all the Funcs passed needs to be the of the same return type.
Upvotes: 0
Views: 576
Reputation: 3060
OK, its not pretty, but I think this is the only way its going to work with generics. It probably not a practical solution:
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 does the samae thing with its Func deligates
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
)
Upvotes: 1
Reputation: 3060
One possibility would be to use a fluent interface instead of a list
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();
Upvotes: 0
Reputation: 28272
Use params Expression<Func<object>>[] list
as a parameter, instead of T
(note that it must be an array for using with params
)
You will, of course, need to cast the result to work with it (unless your process can work with object
... say to do a ToString()
, for example) inside DoSomething
, but how else were you expecting to work with T
when T
can be different depending on the parameter?
Update: I've made an example in this fiddle, but what you can do with this is pretty much limited, so as @juharr stated in the comments, it'd be better if you explained what do you want to do so we can suggest more practical alternatives
Also, if you don't need the expression (just the callback), there's no need to pass a expression, just pass the Func
(modified fiddle)
Upvotes: 2