Ну и еще один этюд.
Приведите пример, как unreachable код может влиять на результат программы. Рефлексия не считается.
С кем обсуждали это в личной переписке — пожалуйста, не торопитесь писать ответ здесь.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main");
string s = "1";
if (s == "1") return;
A.Do();
}
}
public static class A
{
public static readonly Hi h = new Hi();
//static A()
//{
//}public static void Do()
{
}
}
public class Hi
{
public Hi()
{
Console.WriteLine("Hi");
}
}
}
Вроде при таком коде тоже можен работать, но поведение будет "недетерминированно":
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main");
return;
A.Do();
}
}
...
Здравствуйте, Ovl, Вы писали:
N>>Нет, такой код не считается unreachable. Ovl>а какой считается?
8.1 End points and reachability
If a statement can possibly be reached by execution, the statement is said to be reachable. Conversely, if there is no possibility that a statement will be executed, the statement is said to be unreachable. <...>
To determine whether a particular statement or end point is reachable, the compiler performs flow analysis according to the reachability rules defined for each statement. The flow analysis takes into account the values of constant expressions (§7.18) that control the behavior of statements, but the possible values of non-constant expressions are not considered. In other words, for purposes of control flow analysis, a non-constant expression of a given type is considered to have any possible value of that type.
Ovl>зы. опять 3.0 или ранний дотнет можно?
Ну, опять же, я знаю решение, использующее особенности C# 3.0, но буду рад увидеть любые решения.
P.S. Кто не заметил, еще один интересный этюд лежит
Здравствуйте, migel, Вы писали:
M>Я так понял злую шутку сыграл вывод типов лямбды?
Да. M>Что стандарт по этому поводу говорит?
Стандарт говорит (7.4.2.6 Output type inferences), что при выводе типов из анонимной функции используется ее inferred return type. А этот тип (7.4.2.11 Inferred return type) в случае, если тело анонимной функции является блоком, вычисляется как best common type выражений во всех return statements в этом блоке. То есть точно так же, как если бы все эти выражения были элементами неявно типизированого массива.
Здравствуйте, nikov, Вы писали:
N>Стандарт говорит (7.4.2.6 Output type inferences), что при выводе типов из анонимной функции используется ее inferred return type. А этот тип (7.4.2.11 Inferred return type) в случае, если тело анонимной функции является блоком, вычисляется как best common type выражений во всех return statements в этом блоке. То есть точно так же, как если бы все эти выражения были элементами неявно типизированого массива.
Ой, я наврал. Это объяснение подходит для такого случая:
using System;
class Program
{
static void Main()
{
D(() =>
{
return 1;
return 2.2;
});
}
static void D<T>(Func<T> f)
{
Console.WriteLine(typeof(T));
}
}
А для исходного примера надо смотреть 6.6 Method group conversions и 7.4.3.3 Better conversion from expression.
N>А теперь попробуйте раскомментировать строку Foo().
Мастерство не пропьешь
А, если серьезно, то не хорошо это. В 2.0 такая шутка не прокатывает, а в 3 работает. Плохо даже не то что можно именно так, а что уходит строгость. Ну хоть warning можно было дать, что имена одинаковые? Мне кажется можно. Хочется мне именно так делать — ну выключу варнинг в этом месте. А то так скоро и к if (i=5) вернемся.
Впрочем это так... мысли вслух. Сейчас мне докажут что так и нужно и было задумано
Здравствуйте, Димчанский, Вы писали:
Д>Скоро C# превратится в C++... Все возвращается на круги своя.
Тем не менее код на C# остается пригодным для полноценных автоматических рефакторингов, и компилируется в сборки, поддающиеся верификации и интроспекции.
Здравствуйте, nikov, Вы писали:
N>Тем не менее код на C# остается пригодным для полноценных автоматических рефакторингов, и компилируется в сборки, поддающиеся верификации и интроспекции.
Да это понятно. Просто хотелось бы в языке видеть поменьше неоднозначно понимаемых конструкций. Что бы программирование на языке не превращалось в доскональное знание N десятков страниц стандарта, т.е. не попрограммировав месяц вернулся к языку и пишешь сразу, не вспоминая о десятке каких-то нюансов. Ну или по крайней мере, чтобы такие места обзывались какими-нибудь варнингами.
P_A>А, если серьезно, то не хорошо это. В 2.0 такая шутка не прокатывает, а в 3 работает.
Дело в том, что в C# 3.0 появилось дополнительное правило про invocable члены.
P_A>Плохо даже не то что можно именно так, а что уходит строгость. Ну хоть warning можно было дать, что имена одинаковые? Мне кажется можно. Хочется мне именно так делать — ну выключу варнинг в этом месте. А то так скоро и к if (i=5) вернемся. Впрочем это так... мысли вслух. Сейчас мне докажут что так и нужно и было задумано
Мы вчера обсуждали этот код с Эриком Липпертом, и он решил, что это все-таки баг (и я с ним согласен). В случае, когда Foo() раскомментировано, должна возникать ошибка про конфликтующие интерпретации simple name Foo в одном блоке. Скорее всего, это будет исправлено только в следующей версии C#.
Здравствуйте, Димчанский, Вы писали:
Д>Да это понятно. Просто хотелось бы в языке видеть поменьше неоднозначно понимаемых конструкций. Что бы программирование на языке не превращалось в доскональное знание N десятков страниц стандарта, т.е. не попрограммировав месяц вернулся к языку и пишешь сразу, не вспоминая о десятке каких-то нюансов. Ну или по крайней мере, чтобы такие места обзывались какими-нибудь варнингами.
Чтобы на эти нюансы наткнуться, имхо надо ценаправленно их искать.
Здравствуйте, nikov, Вы писали:
N>А теперь попробуйте раскомментировать строку Foo().
Если всё до этого было более-менее терпимо и более-менее объяснимо, то этот случай просто шокирует. Еще пару выкрутасов подобного рода, и новый C# пойдёт в топку за ненадёжность компилятора.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Димчанский, Вы писали:
Д>>Да это понятно. Просто хотелось бы в языке видеть поменьше неоднозначно понимаемых конструкций. Что бы программирование на языке не превращалось в доскональное знание N десятков страниц стандарта, т.е. не попрограммировав месяц вернулся к языку и пишешь сразу, не вспоминая о десятке каких-то нюансов. Ну или по крайней мере, чтобы такие места обзывались какими-нибудь варнингами.
L>Чтобы на эти нюансы наткнуться, имхо надо ценаправленно их искать.
Здравствуйте, vdimas, Вы писали:
V>Если всё до этого было более-менее терпимо и более-менее объяснимо, то этот случай просто шокирует. Еще пару выкрутасов подобного рода, и новый C# пойдёт в топку за ненадёжность компилятора.
Не пойдет, пока такие выкрутасы будут только в специально придуманных примерах. Я с интересом читаю эти топики, но, следует признать, практической пользы от них ноль целых ноль десятых.
... <<RSDN@Home 1.2.0 alpha 4 rev. 1090 on Windows Vista 6.0.6001.65536>>
Здравствуйте, nikov, Вы писали:
N>Ну и еще один этюд. N>Приведите пример, как unreachable код может влиять на результат программы. Рефлексия не считается. N>С кем обсуждали это в личной переписке — пожалуйста, не торопитесь писать ответ здесь.
это конечно интересно, но что по-мне, так это явно не хорошо.
это может говорить о какой-то концептуальной ощибки в дизайне языка
и уж точно это источник hard-to-catch ощибок.
Здравствуйте, AndrewVK, Вы писали:
AVK>Не пойдет, пока такие выкрутасы будут только в специально придуманных примерах. Я с интересом читаю эти топики, но, следует признать, практической пользы от них ноль целых ноль десятых.
Ну да да — особенно с экстеншн методом — который ломает нафиг поведение отлаженного кода
Здравствуйте, AndrewVK, Вы писали:
V>>Если всё до этого было более-менее терпимо и более-менее объяснимо, то этот случай просто шокирует. Еще пару выкрутасов подобного рода, и новый C# пойдёт в топку за ненадёжность компилятора.
AVK>Не пойдет, пока такие выкрутасы будут только в специально придуманных примерах. Я с интересом читаю эти топики, но, следует признать, практической пользы от них ноль целых ноль десятых.
Упомянутый случай легко получить на практике, поэтому необходимо, как минимум, предупреждение от компиллятора.
Здравствуйте, AndrewVK, Вы писали:
S>>Вот до чего доводит педантизм, помноженный на энтузиазм! AVK>Я тебе больше скажу — в C# compiler team есть такой термин — nikov bug.
Мало того, такой термин есть и в ReSharper team, причём у нас он появился скорее всего раньше