All streams
Search
Write a publication
Pull to refresh
9
0
Денис Николаев @DenisNikolayev

Пользователь

Send message
Это как так? r.Element(«Employee») возвращает null и вызов Element(«PersonInfo») у null'а, дает NullReferencesException. Или тут магия?
Ну это же так, рассуждения в слух :) О том, что иногда кажется, что это «должно работать именно так».
Что будет если тег Employee не будет найден?
Окей, тогда хочу пост условия :)
Методы расширения — это функциональщина? Возможно, но писать значительно проще.

   var name = root.Element(«Employee»).Element(«PersonInfo»).Attribute(«Name»).Value() ?? "";


   var name = root.Element("Employee").With(e=>e.Element("PersonInfo").With(e=>e.Element("Name")).With(e=>e.Attribute("Name")).With(e=>e.Value) ?? "";


а я линивый :) и ошибиться боюсь.
Предусловие для For? На сколько я понимаю в For условие проверяется после выполнения тела цикла :)
Согласен. Но на самом деле функциональщина нужна далеко не везде. Например, в моём примере проще сделать так.

static class Ext
{
    public static XElement Element(this XElement el, string name)
    {
         if (el == null) return null;
         return el.Element(name);
    }
}
И читать сложнее :) По крайне мере в C#.
Ну в for ведь разрешили :)
Обожаю F#. Но мы ведь тут обсуждаем, что бы ещё такого можно было бы накрутить на C# :)
Да, согласен. Но чтобы написать правильно тот кусок (с проверками на null), необходимо затратить значительное количество строчек, при написании которых, можно будет отстрелить себе не только ногу, но и голову :)
Самое интересное то, где объявлена repeat. У Вас она за циклом. А зачем она нужна вне цикла?
Если разрешать null, то всё равно придется либо получать значение два раза, либо использовать дополнительную внешнюю переменную.

if (dic[«key»] != null)
{
Console.WriteLine(dic[«key»]);
}

либо

var item = dic[«key»];
if (item != null)
{
}

в монадами хорошо, но кроме фигурных скобок появляются ещё и круглые, а если использовать вложенность, то совсем плохо смотрится.
Ещё есть «неадекватность» по моему мнению в операторе ??

var name = root.Element(«Employee»).Element(«PersonInfo»).Attribute(«Name»).Value ?? "";

я же (вроде как), четко написал компилятору, что меня интересует значение левой части, если оно не пустое, иначе права часть.

Реализовать такое тоже думаю не сложно, объявив набор стандартных исключений, которые глотаются оператором ?? (например, KeyNotFound, NullRefenecesException и т. п.)
TryGetValue — не решает проблему лишней переменной вне условия :)
Монады круто, но в C# синтаксис не очень для них подходит (устанете копаться в закрывающихся скобочках).
К статье ещё можно пункт добавить: «Почему мне надо переменную объявлять вне цикла do-while, чтобы использовать её в проверке выхода»

Почему нельзя написать так:
do
{
bool repeat = // расчет в несколько строк
}
while (repeat);

Вне цикла от переменной нет никакого толку. Ну и соответственно почему нельзя объявить переменну в цикле while-do, а в for можно.

while (bool repeat = true == true) // либо while (bool repeat = true; repeat)
{
  ... 
}
ааа, о втором пункте всю жизнь мечтал
представляете, можно было бы написать такое
var dic = new Dictionary<string, string>();
...
if (var item = dic.TryGetValueOrDefault("Key") != null)
{
   Console.WriteLine(item);
}


куча плюсов такого подхода
1. можно использовать var (сейчас холивар будет);
2. не засоряется область лишними переменными (мне не нужен доступ к переменной item в не цикла, так как она будет равна null).
3. одна строка — вместо двух/трех.

эх, в F# так можно написать и даже больше

// xml предварительно проверили на валидность через xsd.
if (let node = root.SelectSingleNode("node")
      node.Value == "value1" or node.Value == "value2")
{
   ...
}
>>2. Очень, ну просто Очень интересное утверждение. Приведите пруф линк, желательно на MSDN, о том, что в .NET new занимает меньше времени чем new от С++ или alloc objective-c. Иначе ваш комментарий необоснован.

alloc'у очень много времени тратит на поиск свободного места в участках памяти, ему необходимо минимизировать дефрагментацию, потребление памяти и т. п. При этом выделение памяти под объект в C# всегда занимает О(1), при любом количестве созданных объектов.

А всё потому, что сборщик мусора в .Net каждый раз утрамбовывает объекты закрывая пустые места, появившиеся в результате удаления не нужных объектов. Соответственно когда мы вызываем new, .Net просто увеличивает указатель на стек объектов выделяя память одной операцией +sizeof(объект). Соответственно мы тратим много времени на утрамбовку, раз в несколько секунд, но у нас тратится значительно меньше времени на создание нового объекта.
>>1) Почему нельзя при установке приложения скомпилировать байткод в машинный код, как это делает JIT в рантайме? Затраты на компаляцию перед установкой будут не дольше, чем на клики «Далее», а программа будет так же быстро работать, как написанная на С++.

Время полной компиляции, программы, которую я разрабатывал на прошлой работе — равнялась 45 минут, на выделенном сервере. Кушая под 2 гигабайта памяти. Хотя там было всего 5-10 миллионом строк. Даже если считать, что разбор текста тоже занимает время, пусть будет 80%, то у нас выходит: 9 минут ждать запуска — полагаю никакого удовольствия. А если представить сколько кода написано для больших программ (какой-нибудь word, sql server), то думаю заниматься установкой несколько часов Вам бы тоже не захотелось.

И есть у jit'а, ещё одно громадное преимущество, он собирает данные о работе конкретных функций и на основании этих сведений, прям во время работы проводит дополнительную оптимизацию. Статический компилятор в этом ему сильно проигрывает.
>>2) Почему компилятор не может расставить delete сам, вместо того чтобы в рантайме сборщик мусора проводил кучу дорогостоящих операций? Так, например, сделали в Apple — там есть ARC, который на этапе компиляции расставляет нужные инструкции и всё — программа не нуждается в GC и может работать быстро.

Всё довольно банально:
class1
class1 next;

Что будет, если у нас в экземпляре класса1 в поле next будет содержаться this? Тогда при использовании механизма учета ссылок (а это как раз delete в нужных местах), мы придем, что при каждом выходе переменной из области видимости (а это может быть и цикл), нам придется анализировать громадный граф связанных объектов.

   var c = new Class1(); // счетчик ссылок 1
   c.next = c; // счетчик ссылок 2
   delete c; // счетчик ссылок 1 - наш мемлик, либо надо заглянуть во все поля объекта и поискать там циклы


Сборщик мусора, как раз запускается редко, чтобы выявлять такие циклы и разрывать их, при этом минимально влияя на скорость работы. Кстати, и поколения сделаны так же, для оптимизации обхода графов связанных объектов. Если мы уже один раз обошли большой граф и не смоги ничего удалить, то значит в следующий раз вернёмся к нему, когда совсем прижмет.

Кстати, как бы странно не казалось, но такую проблему можно встретить достаточно часто:
— childs, parent (во всяких XDocument'ах);
— списки (двух связанные и односвязанные);
— какие-нибудь менеджеры и т. п.

Information

Rating
Does not participate
Location
Караганда, Карагандинская обл., Казахстан
Date of birth
Registered
Activity