Совсем программерский пост
Aug. 30th, 2007 06:12 pmMono постепенно реализует фичи третьей версии языка C#.
И вот мы пытаемся скомпилить код:
И получаем облом. Понятное дело, фреймворк-то у Mono всего-лишь второй, в нем у списка никакого Where нету. Но компилятор уже умный, и понимает такую хитрую штуку, как статические расширения, так что беду легко можно вылечить, написав следующий класс (обращаем внимание на неуместное с виду слово this у параметра l):
И все вроде-бы клево, и работает зашибись. Класс статических расширений можно описывать где угодно. И компилить хоть в отдельную assembly.
А теперь вопрос: компилятор, чтобы скомпилить код, использующий статические расширения, должен эти расширения найти. И ведь находит, зараза! Он что, просматривает для этого все доступные ему библиотеки?
Исходники его смотреть уж больно неохота...
UPD 1 : Вообще-то, если компилятору нужен тип, а не метод, он тоже его ищет по всем библиотекам. Так что не такой уж и ужасный криминал. Но все же криминал: при поиске типа все, что нужно узнать, для того, чтобы решить, подходит тип или нет, у типа снаружи; при поиске расширения надо всем статическим классам залезть в потроха...
UPD 2 : Антон и Сержик немного успокоили:
Компилятор просматривает все статические классы в доступных сборках, которые доступны через юзинги текущего файла. В сборке сразу сказано, какие неймспейсы она экспортит (и какие из нее, соответственно, можно импортить).
Да, немного лучше. Хотя все равно не фонтан, конечно.
И вот мы пытаемся скомпилить код:
using System;
using System.Collections.Generic;
public class Foo
{
public static void Main()
{
var l = new List<int> {1, 2, 3};
foreach(int i in l.Where(x => x > 1))
Console.WriteLine(i);
}
}
И получаем облом. Понятное дело, фреймворк-то у Mono всего-лишь второй, в нем у списка никакого Where нету. Но компилятор уже умный, и понимает такую хитрую штуку, как статические расширения, так что беду легко можно вылечить, написав следующий класс (обращаем внимание на неуместное с виду слово this у параметра l):
public static class EnumExt
{
///Filtering lambda
public delegate bool Test<T>(T value);
///Filtering method
public static IEnumerable<T> Where<T>(this IEnumerable<T> l, Test<T> t)
{
foreach(T el in l)
if(t(el))
yield return el;
}
}
И все вроде-бы клево, и работает зашибись. Класс статических расширений можно описывать где угодно. И компилить хоть в отдельную assembly.
А теперь вопрос: компилятор, чтобы скомпилить код, использующий статические расширения, должен эти расширения найти. И ведь находит, зараза! Он что, просматривает для этого все доступные ему библиотеки?
Исходники его смотреть уж больно неохота...
UPD 1 : Вообще-то, если компилятору нужен тип, а не метод, он тоже его ищет по всем библиотекам. Так что не такой уж и ужасный криминал. Но все же криминал: при поиске типа все, что нужно узнать, для того, чтобы решить, подходит тип или нет, у типа снаружи; при поиске расширения надо всем статическим классам залезть в потроха...
UPD 2 : Антон и Сержик немного успокоили:
Компилятор просматривает все статические классы в доступных сборках, которые доступны через юзинги текущего файла. В сборке сразу сказано, какие неймспейсы она экспортит (и какие из нее, соответственно, можно импортить).
Да, немного лучше. Хотя все равно не фонтан, конечно.