How to evaluate a lambda expression to determine object type

白昼怎懂夜的黑 提交于 2019-12-25 00:33:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!