.Net Micro Framework的TinyCLR是遵循PC机上的CLR1.0版本的, 这样使得要求CLR版本为2.0以上(提供了泛型)的LINQ无法在Micro Framework之上得到支持, 不过除了LINQ之外的Lambda表达式, 扩展方法等都是可以被编译器编译为各种CLR版本都支持的, 于是我们是不是可以利用编译器和以上的特性来实现一下没有泛型的linq呢?
答案是肯定的, Marc Frei 和 Cuno Pfister 的试验证实了这种可行性, 以下是他们的测试:
Linq
using System.Collections;
using Microsoft.SPOT;
namespace System.Runtime.CompilerServices {
[AttributeUsageAttribute(
AttributeTargets.Assembly
| AttributeTargets.Class
| AttributeTargets.Method)]
sealed class ExtensionAttribute: Attribute {}
}
delegate bool Predicate (object o);
sealed class Enumerator: IEnumerator {
IEnumerator e;
Predicate p;
internal Enumerator (IEnumerator e, Predicate p) {
this.e = e;
this.p = p;
}
object IEnumerator.Current {
get { return e.Current; }
}
void IEnumerator.Reset () {
e.Reset();
}
bool IEnumerator.MoveNext () {
var b = e.MoveNext();
while (b && !p(e.Current)) {
b = e.MoveNext();
}
return b;
}
}
sealed class Filter: IEnumerable {
IEnumerable e;
Predicate p;
internal Filter (IEnumerable e, Predicate p) {
this.e = e;
this.p = p;
}
IEnumerator IEnumerable.GetEnumerator () {
return new Enumerator(e.GetEnumerator(), p);
}
}
static class Program {
static int Count (this IEnumerable e) {
var n = 0;
foreach (var o in e) {
n++;
}
return n;
}
static IEnumerable Where (this IEnumerable e, Predicate p) {
return new Filter(e, p);
}
static void Main () {
var a = new int[] {1, 2, 3, 4, 6, 8, 9, 9, 9};
var n = a.Where(v => (int) v % 2 == 0).Count();
var m = (from v in a where (int) v % 2 == 0 select v).Count();
Debug.Print(n + " " + m);
}
}
你不妨在你的VS2008中新建一个MFConsoleApp测试一下
Enjoy!
黄季冬