Using LINQ in generic collections
- by Hugo S Ferreira
Hi,
Please consider the following snippet from an implementation of the Interpreter pattern:
public override object Execute(Interpreter interpreter, object ctx) {
var list = ctx as IEnumerable<string>;
return (list != null) ? list.FirstOrDefault() : null;
}
What about if I want to use the same function for integers?
public override object Execute(Interpreter interpreter, object ctx) {
var list = ctx as IEnumerable<string>;
if (list != null) return list.FirstOrDefault();
var list = ctx as IEnumerable<int>;
return (list != null) ? list.FirstOrDefault() : null;
}
What I wanted was something like:
public override object Execute(Interpreter interpreter, object ctx) {
var list = ctx as IEnumerable;
return (list != null) ? list.FirstOrDefault() : null;
}
But Linq doesn't act on IEnumerables. Instead, to get to this solution, I would be forced to write something like:
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;
}
Or use a generic method:
public override T Execute<T>(Interpreter interpreter, object ctx) {
var list = ctx as IEnumerable<T>;
return (list != null) ? list.FirstOrDefault() : null;
}
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:
public override object Execute(Interpreter interpreter, object ctx) {
var list = ctx as IEnumerable<object>;
return (list != null) ? list.FirstOrDefault() : null;
}
So, my question is: what's the best way to achieve the intended behavior?
Thanks :-)