【问题标题】:Conditional .OfType()?有条件的 .OfType()?
【发布时间】:2013-10-09 23:40:11
【问题描述】:

假设我们有一个基类 A 和 2 个派生类 B & C。如果我想查询以字符串形式给出的某种类型的实例,我该怎么做?

我想写:

var q = A.OfType<t == "B" ? B : C>()

但这不会编译,我也不想写两个不同的查询:

var q;
if (t == "A") q = A.OfType<B>();
else q = A.OfType<C>();

建议任何人?

【问题讨论】:

  • 这不是 LINQ,我的建议是如果你的第二个代码 sn-p 有效,你应该使用它。
  • OfType&lt;&gt; 的替代品是.Where(x =&gt; x is A)
  • 泛型在编译时发挥作用,所以当然选项 1 不起作用
  • 第二个选项有什么问题?这可能是最好的方法,尽管我会缩短它:var q = t == "B" ? A.OfType&lt;B&gt;() : A.OfType&lt;C&gt;();
  • 我很好奇你想为 q 推断出什么类型。

标签: c# linq


【解决方案1】:

我想出的最接近的是:

var q = a.Where(e => (t == "B" && e is B) || (t != "B" && e is C));

另一种可能性,部分由 cmets 中的 jods 提出:

var q = t == "B"
        ? ((IEnumerable<A>)a.OfType<B>())
        : ((IEnumerable<A>)a.OfType<C>());

但是,在这两种情况下,结果都是 &lt;A&gt; 类型,因为您不能让函数的返回类型依赖于运行时条件,因为它必须在编译时确定。

【讨论】:

  • 这是一种避免“编写两个不同的查询”的可能性,正如 OP 所写的那样。虽然我不得不说我看不到任何好处,而且这个解决方案只能保证速度较慢。
  • @jods 我同意,我也认为这没有任何意义。只是我得到的最接近 OP 要求的东西。
  • 我想答案是 C# 中没有一些聪明的方法来处理这个问题。在这种情况下,上述两个答案中的任何一个似乎都是一条合理的路径。感谢您的建议。
【解决方案2】:

不完全是你想要的,但是三元运算符 (?:) 是个好东西,

var q = (t=="B") ? A.OfType<B>() : A.OfType<C>() ;

(见How to use ternary operator for this statement in c#

【讨论】:

  • ...等之间没有隐式转换
  • 这不会编译 - 三元运算符在两种情况下都必须返回相同的类型。
  • 您可以排除错误,但从技术上讲,您仍然在这里进行两个查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 2018-06-30
相关资源
最近更新 更多