【问题标题】:How to evaluate a lambda expression to determine object type如何评估 lambda 表达式以确定对象类型
【发布时间】:2014-11-18 03:04:45
【问题描述】:
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.
}

这个 lambda 东西对我来说仍然是陌生的。如果我问的是已经在其他地方回答过的明显问题,我深表歉意。

【问题讨论】:

  • 如果没有通用的超类/接口,那么您可以让编译器在编译时检查它...运行它,强制转换并检查异常。
  • 更好的是,使用TypeOfas 并检查是否有任何东西通过过滤器。
  • 您能否编辑您的问题以包含比这更高一级要解决的问题是什么,好吗?了解这一点可能有助于获得更好的答案或为您指明不同的方向。
  • @SJuan76 我更愿意在编译时检查它,但不知道它是如何工作的。我需要能够处理 List、IEnumerable、ObservableCollection、Tomato、TomatoCollection,可能还有更多。由于 lambda 表达式的“伟大”之一是延迟评估/执行,我不理解如何进行编译时检查。

标签: c# lambda expression


【解决方案1】:

回应您的评论

I need to be able to handle List&lt;Tomato&gt;, IEnumerable&lt;Tomato&gt;, ObservableCollection&lt;Tomato&gt;, Tomato, TomatoCollection

前三个(也可能是最后一个)可以在IEnumerable&lt;Tomato&gt; 中恢复。

如果在其中混合返回 Tomato 的 lambda,我认为没有什么意义,可能你会更适合重载方法。

所以:

 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.

如果你想添加Tomato

 public class MyProduce(Func<Tomato> expression) {
      Func<IEnumerable<Tomato>> expression2 = () => ( new Tomato[] { expression() });
      // Here you use expression2 as in the previous constructor.
 }

如果您想将Potato 添加到组合中,请将该类设为通用类或创建两个类共有的超类/接口。

底线是:让你的先决条件更强

如果您允许您的代码接收任何内容,您将无法对您正在处理的内容做出有效假设,并且您的代码最终会变成一堆意大利面条。允许通过 object 并希望您的代码能够处理它,这就是禁止您使用该语言为您提供的工具(您可以用 Javascript 编写,因为这是值得的)。

【讨论】:

  • ArrayList 不是通用的;你可能只是想在那里使用一个数组。
  • @Servy 已修复,谢谢。来自 Java 并且仍在学习 BCL(我对回答的兴趣正在得到纠正):-D。
  • 是的,犯这个错误的总是 Java 用户
  • 感谢@SJuan76 的输入/回复。我们的解决方案中有 513 个“MyProduce”类。我没有为基类或 513 个派生类创建构造函数语法。即 MyTomatos、MyPotatos、MyOnions 等……(我只是想弄清楚如果传入的导致 Potatos 的 lambda 被传递给 MyOnions 构造函数,如何正确抛出异常/投诉……因为 lambda 是延期评估
【解决方案2】:

这是一个做你想做的事的例子。如果你有它,它将在 linqpad 中运行。

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");
    }
}

【讨论】:

  • 感谢您的回复。将在今天早上晚些时候尝试实施这个变体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多