Pull to refresh

Comments 35

UFO just landed and posted this here
Linq весь — тоже duck typing, благодаря чему можно делать linq monads
Не совсем понял в каком месте там duck typing, поясните пожалуйста.
Чтобы компилировались выражения запроса достаточно, чтобы компилятор нашел метод Select, Where и т.д. При этом даже не важно, как компилятор их найде: как статические методы, методы расширения или экземплярные методы.
var q = from x in a select x.B

Для выполнения этого кода необходимо, что бы существовал метод Select либо в самом a, либо как extension метод для a. Тоже самое для джойнов, групп и так далее. А используя SelectMany можно комбинировать вызовы — from x in a from y in b select new {x,y}

Может возникнуть резонный вопрос о том, откуда у итератора могут возникнуть управляемые ресурсы?

Откуда-откуда… открыли коннекшн в БД, вот вам и ресурс. Что характерно, в EF именно так и работает — соединение (при неявном управлении ими) открывается при первом обращении к итератору, а закрывается после его использования.
Еще можно добавить, в пятом шарпе foreach изменил свое поведения и теперь переменная итератора объявляется во внутреннем контексте, а не во внешнем.
Да, причем я не зря в псевдокоде разворота цикла foreach объявил переменную цикла current именно внутри while-а, а не снаружи. И еще, туц.
хак с утиной типизацией, и забить немного на принципы ООП

разработчики языка C# положили на полиморфизм и ряд других принципов ООП

В статье так говорится об утиной типизации, будто строгая типизация и ООП — это буквально синонимы. Однако существуют строго-типизированные не-ООП языки и ООП-языки с динамической (в том числе и утиной) типизацией.
Ну, здесь как минимум забили на полиморфизм.
Кстати, в копилку знаний, если компилятор, определяет, что в данном foreach обрабатываются только массивы (даже если мы его пропустили через ICollection), то IL код получается с перебором массива, без итератора и заметно более быстрый, чем если этот foreach иногда подхватывает и коллекции. Причем, нередко такой foreach еще и оптимальнее for для массивов. Для проверки сделайте метод, который берет ICollection на вход и несколько замеров с массивом, списком, списком + массивом по очереди.

Update:
Пруф с IL листингом: abi.exdream.com/Blog/post/2009/04/22/For-vs-Foreach-Performance.aspx
Поясните что в этом примере происходит? Почему он не работает?
var x2 = new { Items = list.GetEnumerator() };...
Тут Items является свойством, с помощью него инкапсулируется экземпляр энумератора значимого типа. При его получении x2.Items он всегда копирует инкапсулируемое поле. Таким образом, x2.Items.MoveNext() никогда не сдвигает курсор на следующий элемент, а x2.Items.Current всегда содержит значение по-умолчанию.
> Тут Items является свойством

А… никогда не понимал, стремление везде использовать свойства.
Дык, тут можно и с readonly полем пофокусничать:))

class Program
{
    static readonly List<int>.Enumerator Items = (new List<int> { 1, 2, 3 }).GetEnumerator();
    static void Main(string[] args)
    {
        while (Items.MoveNext())
        {
            Console.WriteLine(Items.Current);
        }
    }
}
То есть для компилятора readonly — это тоже самое что свойство {get;}? Печально, что разработчики компилятора упростили себе задачу.
Мне даже стало интересно, чем они должны отличаться, и как это относится к данному случаю.
Да я-то понимаю, в чем тут дело. Чего я не понимаю — так это какого поведения vf1 ожидает от readonly-поля.
Если в двух словах, то для readonly полей мы всегда получаем копию.
Мне всегда казалось, что readonly более строгое утверждение, и соот-но возможны оптимизации которые невозможны для getter. Это же value type, а не ссылка, было бы более логично если бы для стуктуры readonly «заражал» бы всю структуру.
Я не понимаю, в нынешнем ввиде что такое readonly для стуктуры, префикс для каких переменных?! Больше похоже на заплатку, по принципу «чтоб было».
Это же value type, а не ссылка, было бы более логично если бы для стуктуры readonly «заражал» бы всю структуру.

Нет ничего логичного, более того, это нарушение инкапсуляции.

Я не понимаю, в нынешнем ввиде что такое readonly для стуктуры, префикс для каких переменных?!

Не бывает readonly для структуры, бывает readonly для поля.
более того, это нарушение инкапсуляции.


Структуры всегда отличались от классов.

Не бывает readonly для структуры, бывает readonly для поля.

Не придерайтесь к словам, я имел ввиду это:
readonly Struct Member;

Что здесь значит этот префикс? readonly для каких конкретно данных?
Структуры всегда отличались от классов.

Это еще не повод нарушать инкапсуляцию.

Что здесь значит этот префикс? readonly для каких конкретно данных?

Для поля.
Поле в данном случае разве не вся структура целиком? Если нет, то что именно?
Поле — это поле. То, как его содержимое хранится, не должно влиять на его семантику.
Но оно влияет, см. тот пример с которого мы начали разговор! И поэтому поле не может быть просто полем.
Нифига. Семантика поля не меняется, потому что так себя ведет любое value-type поле.

Проблема не в том, что это поле, а в том, что C# вообще позволяет мутабельные value types.
Ну вот, у нас уже есть value-type поля и поля. Тогда повторю вопрос, что именно readonly для value-type поля?
Что этому полю нельзя присвоить значение. Полю, не его содержимому.
Вообще-то я спросил другое. Мне кажется, свою точку зрения я донес, с вами не согласен, спасибо за ответы, на этом заканчиваю.
Здесь создается анонимный тип с одним свойством Items являющийся структурой (поскольку у List a итератор реализован в виде структуры). Далее при каждом обращении к свойству Items в цикле будет возвращена копия именно поэтому мы зациклимся.
«а зачем мне нужно два метода ReadByLine и ReadByLineImpl, почему бы мне не воспользоваться лишь одним методом?»
IEnumerable не вычисляется до момента обращения, поэтому проверку входных параметров делаем отдельно и отлавливаем сразу ошибки, а само вычисление будет отложенным, Как-то так.
Sign up to leave a comment.

Articles