Это загадка, которую я недавно публиковал на Twitter и давал коллегам на работе. Пока что её отгадал только один человек — Mads Torgersen (причём почти сразу).
Напишите валидную C# программу, которая содержит следующую последовательность токенов:
? null :
и которая остаётся валидной, если мы уберём токен null из этой последовательности, т.е. оставим
? :
Пояснения
* Валидная программа — это программа, которая компилируется без ошибок. Она может быть как приложением (.exe), так и библиотекой классов (.dll).
* Комментарии, части строковых литералов, имена регионов, текст в пропущенных секциях (#if false) и т.д. не являются токенами.
* Части токенов не являются токенами (например, символ `:` в выражении `foo::bar` или `?` в выражении `foo ?? bar` не являются токенами)
* Runtime поведение программы несущественно. То, что оно может измениться при удалении токена null, также несущественно.
Здравствуйте, nikov, Вы писали: N>Это загадка, которую я недавно публиковал на Twitter и давал коллегам на работе. Пока что её отгадал только один человек — Mads Torgersen (причём почти сразу). N>Напишите валидную C# программу, которая содержит следующую последовательность токенов:
N>? null :
N>
N>и которая остаётся валидной, если мы уберём токен null из этой последовательности, т.е. оставим
N>? :
N>
N>
Пояснения
N>* Валидная программа — это программа, которая компилируется без ошибок. Она может быть как приложением (.exe), так и библиотекой классов (.dll). N>* Комментарии, части строковых литералов, имена регионов, текст в пропущенных секциях (#if false) и т.д. не являются токенами. N>* Части токенов не являются токенами (например, символ `:` в выражении `foo::bar` или `?` в выражении `foo ?? bar` не являются токенами) N>* Runtime поведение программы несущественно. То, что оно может измениться при удалении токена null, также несущественно.
так? или я условия неправильно понял?
class A
{
void M1()
{
var a = true ? M2(null) : 0;
var b = true ? M2() : 0;
}
int M2()
{
return 0;
}
int M2(Object o)
{
return 0;
}
}
Здравствуйте, nikov, Вы писали:
N>Это загадка, которую я недавно публиковал на Twitter и давал коллегам на работе. Пока что её отгадал только один человек — Mads Torgersen (причём почти сразу).
N>Напишите валидную C# программу, которая содержит следующую последовательность токенов:
N>? null :
N>
N>и которая остаётся валидной, если мы уберём токен null из этой последовательности, т.е. оставим
N>? :
N>
Пока что у меня проблема даже с тем, чтобы хотя бы написать валидную программу с последовательностью токенов ? :.
Прошерстил спеку C# 5.0. Colon можно использовать в:
1. Тернарном операторе: не подходит, между ? и : должен быть expression
2. Указателе базового класса: не подходит, слева от : будет либо идентификатор, либо идентификатор <параметры>
3. Label: не подходит, слева от : должен быть идентификатор
4. Case label: не подходит, слева от : должно быть constant expression
5. Декларации атрибута: не подходит, слева от : будет одно из предопределённых ключевых слов
6. Указании именованного параметра в вызове функции: не подходит, слева от : должен быть идентификатор
7. Указании constraint на параметр типа: не подходит, слева от : должен быть идентификатор
8. Декларации конструктора, для обращения к base(...) или this(...): не подходит, слева от : будет )
9. Декларации enum для указания интегрального базового типа: не походит, слева от : должен быть идентификатор
10. В doc comments, но их мы вроде бы не рассматриваем.
Вроде всё.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>Пока что у меня проблема даже с тем, чтобы хотя бы написать валидную программу с последовательностью токенов ? :. S>Прошерстил спеку C# 5.0. Colon можно использовать в:
если про 6, то там, говорят, еще такое будет:
//monadic null checking —
if (points?.FirstOrDefault()?.X ?? -1) { }
т.е. в этом случае вопрос может относиться к проверке на null. Тогда something? может быть первым выражением перед двоеточием в тернарном операторе.
Здравствуйте, SergeyT., Вы писали:
ST>Это не совсем честно, поскольку изменение заключается не только в удалении токена null, но и еще одного выражения
Здравствуйте, nikov, Вы писали:
N>Напишите валидную C# программу, которая содержит следующую последовательность токенов:
N>? null :
N>
N>и которая остаётся валидной, если мы уберём токен null из этой последовательности, т.е. оставим
N>? :
N>
Ну, почти...
public struct Dummy : IDisposable
{
public void Dispose()
{
}
public static implicit operator bool(Dummy d)
{
return true;
}
public static implicit operator Dummy(bool b)
{
return true;
}
}
class Program
{
static bool Dummy = true;
static void Main()
{
object o = null;
Dummy? d = new Dummy();
using
(
Dummy ?
Dummy = o is Dummy
? null :
d
){}
using
(
(bool)
Dummy ?
Dummy = o is Dummy
? :
d
){}
}
}
Осталось понять, почему без выделенного перестает компилиться. Кто поможет?
Здравствуйте, scale_tone, Вы писали:
_>Осталось понять, почему без выделенного перестает компилиться. Кто поможет?
Стоп! Оно же скомпилировалось!! Voila!!!
public struct Dummy : IDisposable
{
public void Dispose()
{
}
public static implicit operator bool(Dummy d)
{
return true;
}
public static implicit operator Dummy(bool b)
{
return true;
}
}
class Program
{
static bool Dummy = true;
static void Main()
{
object o = null;
Dummy? d = new Dummy();
using
(
Dummy ?
Dummy = o is Dummy
? null :
d
){}
using
(
Dummy ?
Dummy = o is Dummy
? :
d
){}
}
}
Здравствуйте, scale_tone, Вы писали:
_>И еще интересно, зачем компилятор позволяет делать такое: _>
_> using(S? s = null){}
_>
Видимо, потому что вместо null может быть более сложный инициализатор (вызов метода, например), который может вернуть как null, так и значение, которое в конце нужно будет освободить с помощью Dispose. Точно так же, как и с ссылочными типами.
Здравствуйте, nikov, Вы писали:
N>Видимо, потому что вместо null может быть более сложный инициализатор (вызов метода, например), который может вернуть как null, так и значение, которое в конце нужно будет освободить с помощью Dispose. Точно так же, как и с ссылочными типами.