Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing LINQ in generic collections
    text
    copied!<p>Please consider the following snippet from an implementation of the Interpreter pattern:</p> <pre><code>public override object Execute(Interpreter interpreter, object ctx) { var list = ctx as IEnumerable&lt;string&gt;; return (list != null) ? list.FirstOrDefault() : null; } </code></pre> <p>What about if I want to use the same function for integers?</p> <pre><code>public override object Execute(Interpreter interpreter, object ctx) { var list = ctx as IEnumerable&lt;string&gt;; if (list != null) return list.FirstOrDefault(); var list = ctx as IEnumerable&lt;int&gt;; return (list != null) ? list.FirstOrDefault() : null; } </code></pre> <p>What I wanted was something like:</p> <pre><code>public override object Execute(Interpreter interpreter, object ctx) { var list = ctx as IEnumerable; return (list != null) ? list.FirstOrDefault() : null; } </code></pre> <p>But Linq doesn't act on IEnumerables. Instead, to get to this solution, I would be forced to write something like:</p> <pre><code>public override object Execute(Interpreter interpreter, object ctx) { var list = ctx as IEnumerable; if (list != null) foreach(var i in list) { yield return i; return; } return null; } </code></pre> <p>Or use a generic method:</p> <pre><code>public override T Execute&lt;T&gt;(Interpreter interpreter, object ctx) { var list = ctx as IEnumerable&lt;T&gt;; return (list != null) ? list.FirstOrDefault() : null; } </code></pre> <p>Which would break the Interpreter pattern (as it was implemented in this system). Covariance would also fail (at least in C#3), though would it work, it would be the exact behavior I wanted:</p> <pre><code>public override object Execute(Interpreter interpreter, object ctx) { var list = ctx as IEnumerable&lt;object&gt;; return (list != null) ? list.FirstOrDefault() : null; } </code></pre> <p>So, my question is: what's the best way to achieve the intended behavior?</p> <hr> <p><strong>Addendum:</strong> digEmAll suggested something like the following code:</p> <pre><code>var list = ctx as IEnumerable; return (list != null) ? list.Cast&lt;object&gt;().FirstOrDefault() : null; </code></pre> <p>This is a good answer for stuff like FirstOrDefault(). The problem comes with things like Reverse:</p> <pre><code>var list = ctx as IEnumerable; return (list != null) ? list.Cast&lt;object&gt;().Reverse() : null; </code></pre> <p>I could fed this method a <code>List&lt;int&gt;</code> but I would get back a <code>List&lt;object&gt;</code>. No way to get around covariance, I know. So I guess digEmAll code is the best answer so far.</p> <hr> <p>Thanks :-)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload