问题
public class Tomato
{}
public class Potato
{}
public class UIPotatoBinding(Expression<Func<object>> expression)
{
// What to put here to make sure lambda results in Potato(s)
}
public class UITomatoBinding(Expression<Func<object>> expression)
{
// What code do I need to put here to determine if the lambda expression being passed in
// results in Tomato, List<Tomato>, IEnumerable<Tomato>, ObservableCollection<Tomato>
// TomatoCollection, or some other Tomato related Linq construct.
}
This lambda stuff is still foreign to me. I apologize if I am asking something obvious that has been answered elsewhere already.
回答1:
Here is an example to do what you want. Will run in linqpad if you have it.
void Main()
{
Expression<Func<object>> f = () => new Potato();
Helper.MyProduce(f);
}
public class Tomato
{}
public class Potato
{}
public static class Helper
{
public static void MyProduce(Expression<Func<object>> expression)
{
var func = expression.Compile();
var result = func();
if(result is Tomato)
Console.Write("Tomato");
else if (result is Potato)
Console.Write("Potato");
else
Console.Write("Unknown");
}
}
回答2:
In response to your comment
I need to be able to handle List<Tomato>, IEnumerable<Tomato>, ObservableCollection<Tomato>, Tomato, TomatoCollection
The first three of them (and possibly the last one) can be resumed in IEnumerable<Tomato>
.
I see little sense if mixing a lambda that returns Tomato
in these, probably you would be better suited by an overloaded method.
So:
public class MyProduce(Func<IEnumerable<Tomato>> expression) // No need to make it an expression, so you allow for an already compiled lambda to be used.
if you want to add the Tomato
public class MyProduce(Func<Tomato> expression) {
Func<IEnumerable<Tomato>> expression2 = () => ( new Tomato[] { expression() });
// Here you use expression2 as in the previous constructor.
}
If you want to add Potato
to the mix, either make the class generic or create a superclass / interface common to both classes.
The bottom line is: make your preconditions stronger.
If you allow your code to receive anything, you won't be able to make a valid assumption of what you are dealing with and your code will end being a lot of spaggetti. Allowing the pass of an object
and hoping for your code to deal with it is forbidding you to use the facilities the language provide you (you could be writting in Javascript, for what is worth).
来源:https://stackoverflow.com/questions/19992057/how-to-evaluate-a-lambda-expression-to-determine-object-type