SlideShare a Scribd company logo
Билет на DotNext 2018 Piter (22-23 апреля) - 1 штука
Билет на PHDays (15-16 мая) - 4 штуки
Годовая подписка на продукты JetBrains - 3 штуки
Книга Марка Симана с автографом - уникальный экземпляр
Браслет Xiaomi Mi Band 2 - 1 штука
+ Футболка MskDotNet - 15 штук
Для участия в викторине зайдите на
www.kahoot.it
и введите следующий PIN:
true false
null зависит
void Main() {
//код
}
1:00
class A {
void Do(int t) {
WriteLine("int: {0}", t);
}
}
class B : A {
void Do(long t) {
WriteLine("long: {0}", t);
}
}
void Main() {
int arg = 5;
var obj = new B();
obj.Do(arg);
}
int:5
Не скомпилируется
long:5
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: B (B:5)
Пояснение:
Компилятор при резолве вызова
видит подходящую сигнатуру в
унаследованном классе и дальше
ничего не ищет. Так что вызван будет
метод класса B.
abstract class Device {
abstract void Initialize();
protected Device() { Initialize(); }
}
class Phone : Device {
private readonly bool? wifi = false;
public Phone() { wifi = true; }
public override void Initialize() {
WriteLine($"WiFi = {wifi}");
}
}
void Main() {
var phone = new Phone();
phone.Initialize();
}
true, false false, true
null, true null, false
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: B (false, true)
Пояснение:
При вызове конструктора унаследованного класса,
сначала произойдёт вызов конструктора базового класса.
То есть, тело конструктора унаследованного класса не
будет выполнено до завершения выполнения тела
конструктора базового класса.
class Base {
virtual event EventHandler SomeEvent;
void InvokeSomeEvent() {
SomeEvent?.Invoke(this,
EventArgs.Empty);
}
}
class Derived : Base {
override event EventHandler SomeEvent;
}
void Main() {
var derived = new Derived();
derived.SomeEvent +=
(s, e) => WriteLine("Hello!");
derived.InvokeSomeEvent();
}
Hello! Не скомпилируется
Ничего не будет
выведено
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: C (ничего не будет выведено)
Пояснение:
Cобытие (field-like event) в базовом классе разворачивается в
пару открытых методов add/remove
и закрытое поле делегата с типом EventHandler.
Подписка происходит через эти методы add/remove.
В классе Derived также генерируется свое собственное закрытое
поле и именно оно изменяется в классе Derived.
То есть, мы имеем два разных делегата.
Подписываемся на унаследованный, а вызываем базовый.
http://sergeyteplyakov.blogspot.ru/2011/02/c.html
class C {
static void M(string x) {
WriteLine("static M");
}
void M(object s) {
WriteLine("instance M");
}
}
static void Main() {
C c = new C();
c.M("hello");
}
static M instance M
Не скомпилируется
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: С (не скомпилируется)
Пояснение:
Правила C# говорят о том, что сначала ищется наилучшее совпадение
по аргументам, а затем отсекаются статические вызовы, сделанные
через экземпляр.
error CS0176: Member 'C.M(string)' cannot be accessed with an instance
reference; qualify it with a type name instead
class C {
static void M(string x) {
WriteLine("static M");
}
void M(object s) {
WriteLine("instance M");
}
}
class B {
public C C = new C();
public void N() { C.M(""); }
}
static void Main() {
B b = new B();
b.N();
}
static M instance M
Не скомпилируется
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: A (static M)
Пояснение:
Эрик Липперт называет это проблему "the Color Color problem".
Есть коллизия между вызовом статического метода на типе C и вызовом
экземплярного метода на свойстве C. Коллизия имён.
Пункт 7.5.4.1 спецификации C# 3.0 определяет, что вызван будет
статический метод.
public void Closure() {
IEnumerable<char> str = "abcdefu";
string vowels = "aeiou";
for (var i = 0; i < vowels.Length; i++) {
str = str.Where(c => c != vowels[i]);
}
WriteLine(new string(str.ToArray()));
}
bcdf abcdef
исключение зависит
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: С (исключение)
Пояснение:
Итератор дойдёт до 5.
Когда произойдёт непосредственный запуск Where,
будет выброшен ArrayOutOfBoundary.
public void Closure() {
IEnumerable<char> str2 = "abcdefu";
foreach (var vowel in "aeiou") {
str2 = str2.Where(c => c != vowel);
}
WriteLine(new string(str2.ToArray()));
}
bcdf abcdef
зависит исключение
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: С (зависит)
Пояснение:
В старых компиляторах замыкание в
foreach отработало бы только последнюю гласную "u".
В новых компиляторах отфильтровались бы все гласные.
void Test(out int x, out int y) {
x = 42;
y = 123;
Console.WriteLine(x == y);
}
всегда true всегда false
зависит
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: С (зависит)
Пояснение:
Если вызвать эту функцию, передав в качестве аргументов
ту же переменную, то результатом будет true.
void DivideByZeroInt() {
int a = 7;
int b = 0;
int result = a / b;
Console.WriteLine(result);
}
исключение
0
infinity
void DivideByZeroDouble() {
double a = 7;
double b = 0;
double result = a / b;
Console.WriteLine(result);
}
void DivideByZeroDecimal() {
decimal a = 7;
decimal b = 0;
decimal result = a / b;
Console.WriteLine(result);
}
исключение
исключение
0
исключение
infinity
infinity
исключение
исключение
infinity
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: D (исключение, исключение, Infinity)
Пояснение:
Целочисленный тип и децимальный
считают ошибкой деление на ноль.
Тип с плавающей точкой оценивает деление на ноль
как деление на значение очень близкое к нулю,
возвращая Infinity.
interface IFoo { void FooThings(); }
interface IBar { void BarThings(); }
class Implementer : IFoo, IBar {
void FooThings() { WriteLine("Foo"); }
void BarThings() { WriteLine("Bar"); }
}
static class ExtensionMethods {
static void Extend(this IFoo item) {
item.FooThings();
}
static void Extend<T>(this T item)
where T: IBar {
item.BarThings();
}
}
static void Main() {
var f1 = new Implementer();
f1.Extend();
}
Foo
Bar
Не скомпилируется
1:301:291:281:271:261:251:241:231:221:211:201:191:181:171:161:151:141:131:121:111:101:091:081:071:061:051:041:031:021:011:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:30
Ответ: B (Bar)
Пояснение:
Компилятор пытается найти наилучшее соответствие.
Тип Impl, несмотря на реализацию интерфейса лучше
подходит для обобщения.
Чтобы вызвать через IFoo, нужно объявить тип переменной
как IFoo или скастоваться к IFoo явно.
struct Customer {
public int Age { get; private set; }
public Customer(int age) {
Age = age;
}
public int Increment() {
return ++Age;
}
}
void Main() {
var list = new List<Customer> {
new Customer(age: 5)
};
list[0].Increment();
WriteLine($"{list[0].Age}");
var array = new[] {new Customer(age: 5)};
array[0].Increment();
WriteLine($"{array[0].Age}");
}
5,5
6,6
5,6
6,5
1:301:291:281:271:261:251:241:231:221:211:201:191:181:171:161:151:141:131:121:111:101:091:081:071:061:051:041:031:021:011:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:30
Ответ: C (5,6)
Пояснение:
Взятие элемента по индексу с листа возвращает копию.
Для массива компилятор генерирует инструкцию «ldelema»
(оптимизация), что позволяет взять ссылку, а не копию.
static void Main() {
int? one = 1;
int? nill = null;
WriteLine(one <= nill);
WriteLine(one >= nill);
WriteLine(one != nill);
var comparer = Comparer<int?>.Default;
WriteLine(comparer.Compare(one, nill));
}
true, false, false, 0
false, false, true, 0
false, false, true, 1
true, true, true, 0
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: B (false, false, true, 1)
Пояснение:
null-значения не упорядочены по отношению к не null.
Однако это не делает null равным единице.
Результат возвращаемый компаратором противоречит тому,
что null-значения не упорядочены относительно не null-значений.
Дефолтовые компараторы реализуют семантику сортировки с null
значениями, где null всегда меньше любого значения.
static void Main() {
int? nill = null;
WriteLine(nill <= nill);
WriteLine(nill >= nill);
WriteLine(nill == nill);
}
true, false, false
false, false, true
false, true, false
true, true, true
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: С (false, false, true)
Пояснение:
null-значения не упорядочены по отношению к не null.
Однако операция сравнения возвращает true.
static void Main() {
double a = Math.Round(5.5);
double b = Math.Round(6.5);
WriteLine(a == 6);
WriteLine(b == 7);
}
true, true
true, false
false, false
false, true
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: C (true, false)
Пояснение:
Режим округления по умолчанию установлен в ToEven.
То есть, округление производится к ближайшему чётному числу.
В обоих случаях ближайшее чётное = 6.
static void Main() {
const double d1 = 0.1;
const double d2 = 0.2;
const double d3 = 0.3;
const double d4 = d1 + d1;
const double d5 = d1 + d2;
WriteLine(d2 == d4);
WriteLine(d3 == d5);
}
true, true
true, false
false, false
false, true
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: С (true, false)
Пояснение:
Числа с плавающей точкой представлены в формате IEEE 754.
Числа с плавающей точкой представлены с ошибками округления.
В бинарном представлении так получается, что
0.1+0.1=0.2, но 0.1+0.2>0.3.
static void Main() {
double a = 1.0 / 10;
double b = a * 10;
double c = a + a + a + a + a +
a + a + a + a + a;
WriteLine(b == 1.0);
WriteLine(c == 1.0);
}
true, true
true, false
false, false
false, true
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: С (true, false)
Пояснение:
Арифметика в C# реализована таким образом,
что операция умножения уменьшает ошибку округления.
В то же время, операция сложения только увеличивает ошибку
округления.
В любом случае - в лоб сравнивать числа с плавающей точкой это
плохая практика.
static void OverflowDecimal() {
decimal max = decimal.MaxValue;
decimal next = max + 1;
WriteLine(next > max);
}
static void OverflowDouble() {
double max = double.MaxValue;
double next = max + 1;
WriteLine(next == max);
}
true, исключение
исключение, false
true, true
исключение, true
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: D (исключение, true)
Пояснение:
decimal строго следит за переполнением и в случае оного
выбрасывает исключение.
Такое поведение не зависит от глобального флага проверки на
переполнение.
double реализован таким образом, что прибавление
"незначительного" числа к максимуму никак учитывается.
Максимум останется максимумом.
static void Main() {
decimal x = 1.0m;
decimal y = 1.00m;
WriteLine(x == y);
WriteLine(x.ToString() == y.ToString());
}
true, true
true, false
false, false
false, true
1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
Ответ: С (true, false)
Пояснение:
Значения абсолютно равны.
ToString выводит значение, учитывая количество разрядов после
запятой.
static class Extensions {
static IEnumerable<TResult> Convert<TResult>
(this IEnumerable sequence) {
foreach (var item in sequence) {
//it works!
object runtimeItem = item;
yield return (TResult) runtimeItem;
}
}
}
static void Main() {
var ints = new List<int>() {
1, 2, 3, 4, 5
};
var result1 = ints.Convert<double>()
.Select(x => x);
var result2 = ints.Cast<double>()
.Select(x => x);
}
сконвертит, сконвертит
исключение, исключение
сконвертит, исключение
исключение, сконвертит
1:301:291:281:271:261:251:241:231:221:211:201:191:181:171:161:151:141:131:121:111:101:091:081:071:061:051:041:031:021:011:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:30
Ответ: B (исключение, исключение)
Пояснение:
В первом случае получим InvalidCast при попытке
приведения object к TResult (double).
Во втором случае (.Cast<double>) в рантайме будет приведение
object к double. Это вызовет InvalidCastException.
static class Extensions {
static IEnumerable<TResult> Convert<TResult>
(this IEnumerable sequence) {
foreach (var item in sequence) {
//it works!
dynamic runtimeItem = item;
yield return (TResult) runtimeItem;
}
}
}
static void Main() {
var ints = new List<int>() { 1, 2, 3, 4, 5 };
var result1 = ints.Convert<double>()
.Select(x => x);
var result2 = from c in ints
select (double)c;
}
сконвертит, сконвертит
исключение, исключение
сконвертит, исключение
исключение, сконвертит
1:301:291:281:271:261:251:241:231:221:211:201:191:181:171:161:151:141:131:121:111:101:091:081:071:061:051:041:031:021:011:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:30
Ответ: A (сконвертит, сконвертит)
Пояснение:
В первом случае мы с помощью dynamic
смотрим на рантаймовый тип, что позволяет
его корректно скастовать.
Во втором случае мы явно в компайл-тайме
определяем тип для приведения в select.
Поэтому конвертация пройдёт успешно.
Билет на DotNext 2018 Piter (22-23 апреля) - 1 штука
Билет на PHDays (15-16 мая) - 4 штуки
Годовая подписка на продукты JetBrains - 3 штуки
Книга Марка Симана с автографом - уникальный экземпляр
Браслет Xiaomi Mi Band 2 - 1 штука
+ Футболка MskDotNet - 15 штук

More Related Content

PPTX
Deep Dive C# by Sergey Teplyakov
PDF
PVS-Studio в 2021 - Примеры ошибок
PPTX
Принципы работы статического анализатора кода PVS-Studio
PPTX
C#. От основ к эффективному коду
PPTX
C sharp deep dive
PPTX
C# Deep Dive
PPTX
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Deep Dive C# by Sergey Teplyakov
PVS-Studio в 2021 - Примеры ошибок
Принципы работы статического анализатора кода PVS-Studio
C#. От основ к эффективному коду
C sharp deep dive
C# Deep Dive
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...

Similar to Викторина MskDotNet Субботник (20)

PPTX
Язык программирования C#
PDF
Иван Иноземцев — Fantom
PDF
Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур
ODP
PPTX
Что могут статические анализаторы, чего не могут программисты и тестировщики
PPTX
Статический анализ кода: современный взгляд
PPTX
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
PDF
Поиск ошибок в программах на языке C#
PDF
На что способны современные статические анализаторы для C#
PDF
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
PPTX
Опыт разработки статического анализатора кода
PPTX
В помощь разработчику: мини-анализатор кода
PDF
Большой брат помогает тебе
PDF
Продолжаем говорить про арифметику
PPTX
Николай Гусев «Функциональное программирование для C# разработчиков»
PPT
2 Константы и поля; методы и параметры; свойства.ppt
PPT
лекция 2 3 новые
PDF
Tricky Java Generics
PDF
1. Типы данных. Операции. Ввод и вывод C#
PDF
Продолжаем говорить о микрооптимизациях .NET-приложений
Язык программирования C#
Иван Иноземцев — Fantom
Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур
Что могут статические анализаторы, чего не могут программисты и тестировщики
Статический анализ кода: современный взгляд
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Поиск ошибок в программах на языке C#
На что способны современные статические анализаторы для C#
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Опыт разработки статического анализатора кода
В помощь разработчику: мини-анализатор кода
Большой брат помогает тебе
Продолжаем говорить про арифметику
Николай Гусев «Функциональное программирование для C# разработчиков»
2 Константы и поля; методы и параметры; свойства.ppt
лекция 2 3 новые
Tricky Java Generics
1. Типы данных. Операции. Ввод и вывод C#
Продолжаем говорить о микрооптимизациях .NET-приложений
Ad

More from MskDotNet Community (18)

PPTX
Антон Сысоев «IIoT: на границе HW и .NET»
PDF
Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...
PDF
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
PPTX
Владимир Кочетков "OWASP TOP 10 для.NET"
PDF
Дмитрий Сошников Искусственный интеллект и нейросети для .NET-разработчиков
PDF
Елизавета Голенок Переходим на mono или как это было
PDF
Иван Кочуркин. Теория и практика парсинга формальных языков
PPTX
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
PDF
Павел Притчин "Конфигурации в.NET"
PPTX
Андрей Кирпичев "Гибкая модульность инструментами АОП"
PPTX
Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере"
PDF
Андрей Матвеев "Основные принципы микросервисов и их реализации"
PDF
Александр Сурков «Вещи» в «Интернете вещей»
PDF
Петр Тимошевский «Industrial IoT на практике»
PDF
Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...
PDF
Илья Ефимов «IoC/DI на примере Autofac»
PDF
Кирилл Маурин «Проектирование и разработка модульных приложений»
PDF
Владимир Кошелев «Автоматический поиск ошибок»
Антон Сысоев «IIoT: на границе HW и .NET»
Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Владимир Кочетков "OWASP TOP 10 для.NET"
Дмитрий Сошников Искусственный интеллект и нейросети для .NET-разработчиков
Елизавета Голенок Переходим на mono или как это было
Иван Кочуркин. Теория и практика парсинга формальных языков
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
Павел Притчин "Конфигурации в.NET"
Андрей Кирпичев "Гибкая модульность инструментами АОП"
Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере"
Андрей Матвеев "Основные принципы микросервисов и их реализации"
Александр Сурков «Вещи» в «Интернете вещей»
Петр Тимошевский «Industrial IoT на практике»
Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...
Илья Ефимов «IoC/DI на примере Autofac»
Кирилл Маурин «Проектирование и разработка модульных приложений»
Владимир Кошелев «Автоматический поиск ошибок»
Ad

Викторина MskDotNet Субботник

  • 1. Билет на DotNext 2018 Piter (22-23 апреля) - 1 штука Билет на PHDays (15-16 мая) - 4 штуки Годовая подписка на продукты JetBrains - 3 штуки Книга Марка Симана с автографом - уникальный экземпляр Браслет Xiaomi Mi Band 2 - 1 штука + Футболка MskDotNet - 15 штук
  • 2. Для участия в викторине зайдите на www.kahoot.it и введите следующий PIN:
  • 3. true false null зависит void Main() { //код } 1:00
  • 4. class A { void Do(int t) { WriteLine("int: {0}", t); } } class B : A { void Do(long t) { WriteLine("long: {0}", t); } } void Main() { int arg = 5; var obj = new B(); obj.Do(arg); } int:5 Не скомпилируется long:5 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 5. Ответ: B (B:5) Пояснение: Компилятор при резолве вызова видит подходящую сигнатуру в унаследованном классе и дальше ничего не ищет. Так что вызван будет метод класса B.
  • 6. abstract class Device { abstract void Initialize(); protected Device() { Initialize(); } } class Phone : Device { private readonly bool? wifi = false; public Phone() { wifi = true; } public override void Initialize() { WriteLine($"WiFi = {wifi}"); } } void Main() { var phone = new Phone(); phone.Initialize(); } true, false false, true null, true null, false 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 7. Ответ: B (false, true) Пояснение: При вызове конструктора унаследованного класса, сначала произойдёт вызов конструктора базового класса. То есть, тело конструктора унаследованного класса не будет выполнено до завершения выполнения тела конструктора базового класса.
  • 8. class Base { virtual event EventHandler SomeEvent; void InvokeSomeEvent() { SomeEvent?.Invoke(this, EventArgs.Empty); } } class Derived : Base { override event EventHandler SomeEvent; } void Main() { var derived = new Derived(); derived.SomeEvent += (s, e) => WriteLine("Hello!"); derived.InvokeSomeEvent(); } Hello! Не скомпилируется Ничего не будет выведено 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 9. Ответ: C (ничего не будет выведено) Пояснение: Cобытие (field-like event) в базовом классе разворачивается в пару открытых методов add/remove и закрытое поле делегата с типом EventHandler. Подписка происходит через эти методы add/remove. В классе Derived также генерируется свое собственное закрытое поле и именно оно изменяется в классе Derived. То есть, мы имеем два разных делегата. Подписываемся на унаследованный, а вызываем базовый. http://sergeyteplyakov.blogspot.ru/2011/02/c.html
  • 10. class C { static void M(string x) { WriteLine("static M"); } void M(object s) { WriteLine("instance M"); } } static void Main() { C c = new C(); c.M("hello"); } static M instance M Не скомпилируется 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 11. Ответ: С (не скомпилируется) Пояснение: Правила C# говорят о том, что сначала ищется наилучшее совпадение по аргументам, а затем отсекаются статические вызовы, сделанные через экземпляр. error CS0176: Member 'C.M(string)' cannot be accessed with an instance reference; qualify it with a type name instead
  • 12. class C { static void M(string x) { WriteLine("static M"); } void M(object s) { WriteLine("instance M"); } } class B { public C C = new C(); public void N() { C.M(""); } } static void Main() { B b = new B(); b.N(); } static M instance M Не скомпилируется 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 13. Ответ: A (static M) Пояснение: Эрик Липперт называет это проблему "the Color Color problem". Есть коллизия между вызовом статического метода на типе C и вызовом экземплярного метода на свойстве C. Коллизия имён. Пункт 7.5.4.1 спецификации C# 3.0 определяет, что вызван будет статический метод.
  • 14. public void Closure() { IEnumerable<char> str = "abcdefu"; string vowels = "aeiou"; for (var i = 0; i < vowels.Length; i++) { str = str.Where(c => c != vowels[i]); } WriteLine(new string(str.ToArray())); } bcdf abcdef исключение зависит 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 15. Ответ: С (исключение) Пояснение: Итератор дойдёт до 5. Когда произойдёт непосредственный запуск Where, будет выброшен ArrayOutOfBoundary.
  • 16. public void Closure() { IEnumerable<char> str2 = "abcdefu"; foreach (var vowel in "aeiou") { str2 = str2.Where(c => c != vowel); } WriteLine(new string(str2.ToArray())); } bcdf abcdef зависит исключение 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 17. Ответ: С (зависит) Пояснение: В старых компиляторах замыкание в foreach отработало бы только последнюю гласную "u". В новых компиляторах отфильтровались бы все гласные.
  • 18. void Test(out int x, out int y) { x = 42; y = 123; Console.WriteLine(x == y); } всегда true всегда false зависит 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 19. Ответ: С (зависит) Пояснение: Если вызвать эту функцию, передав в качестве аргументов ту же переменную, то результатом будет true.
  • 20. void DivideByZeroInt() { int a = 7; int b = 0; int result = a / b; Console.WriteLine(result); } исключение 0 infinity void DivideByZeroDouble() { double a = 7; double b = 0; double result = a / b; Console.WriteLine(result); } void DivideByZeroDecimal() { decimal a = 7; decimal b = 0; decimal result = a / b; Console.WriteLine(result); } исключение исключение 0 исключение infinity infinity исключение исключение infinity 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 21. Ответ: D (исключение, исключение, Infinity) Пояснение: Целочисленный тип и децимальный считают ошибкой деление на ноль. Тип с плавающей точкой оценивает деление на ноль как деление на значение очень близкое к нулю, возвращая Infinity.
  • 22. interface IFoo { void FooThings(); } interface IBar { void BarThings(); } class Implementer : IFoo, IBar { void FooThings() { WriteLine("Foo"); } void BarThings() { WriteLine("Bar"); } } static class ExtensionMethods { static void Extend(this IFoo item) { item.FooThings(); } static void Extend<T>(this T item) where T: IBar { item.BarThings(); } } static void Main() { var f1 = new Implementer(); f1.Extend(); } Foo Bar Не скомпилируется 1:301:291:281:271:261:251:241:231:221:211:201:191:181:171:161:151:141:131:121:111:101:091:081:071:061:051:041:031:021:011:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:30
  • 23. Ответ: B (Bar) Пояснение: Компилятор пытается найти наилучшее соответствие. Тип Impl, несмотря на реализацию интерфейса лучше подходит для обобщения. Чтобы вызвать через IFoo, нужно объявить тип переменной как IFoo или скастоваться к IFoo явно.
  • 24. struct Customer { public int Age { get; private set; } public Customer(int age) { Age = age; } public int Increment() { return ++Age; } } void Main() { var list = new List<Customer> { new Customer(age: 5) }; list[0].Increment(); WriteLine($"{list[0].Age}"); var array = new[] {new Customer(age: 5)}; array[0].Increment(); WriteLine($"{array[0].Age}"); } 5,5 6,6 5,6 6,5 1:301:291:281:271:261:251:241:231:221:211:201:191:181:171:161:151:141:131:121:111:101:091:081:071:061:051:041:031:021:011:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:30
  • 25. Ответ: C (5,6) Пояснение: Взятие элемента по индексу с листа возвращает копию. Для массива компилятор генерирует инструкцию «ldelema» (оптимизация), что позволяет взять ссылку, а не копию.
  • 26. static void Main() { int? one = 1; int? nill = null; WriteLine(one <= nill); WriteLine(one >= nill); WriteLine(one != nill); var comparer = Comparer<int?>.Default; WriteLine(comparer.Compare(one, nill)); } true, false, false, 0 false, false, true, 0 false, false, true, 1 true, true, true, 0 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 27. Ответ: B (false, false, true, 1) Пояснение: null-значения не упорядочены по отношению к не null. Однако это не делает null равным единице. Результат возвращаемый компаратором противоречит тому, что null-значения не упорядочены относительно не null-значений. Дефолтовые компараторы реализуют семантику сортировки с null значениями, где null всегда меньше любого значения.
  • 28. static void Main() { int? nill = null; WriteLine(nill <= nill); WriteLine(nill >= nill); WriteLine(nill == nill); } true, false, false false, false, true false, true, false true, true, true 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 29. Ответ: С (false, false, true) Пояснение: null-значения не упорядочены по отношению к не null. Однако операция сравнения возвращает true.
  • 30. static void Main() { double a = Math.Round(5.5); double b = Math.Round(6.5); WriteLine(a == 6); WriteLine(b == 7); } true, true true, false false, false false, true 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 31. Ответ: C (true, false) Пояснение: Режим округления по умолчанию установлен в ToEven. То есть, округление производится к ближайшему чётному числу. В обоих случаях ближайшее чётное = 6.
  • 32. static void Main() { const double d1 = 0.1; const double d2 = 0.2; const double d3 = 0.3; const double d4 = d1 + d1; const double d5 = d1 + d2; WriteLine(d2 == d4); WriteLine(d3 == d5); } true, true true, false false, false false, true 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 33. Ответ: С (true, false) Пояснение: Числа с плавающей точкой представлены в формате IEEE 754. Числа с плавающей точкой представлены с ошибками округления. В бинарном представлении так получается, что 0.1+0.1=0.2, но 0.1+0.2>0.3.
  • 34. static void Main() { double a = 1.0 / 10; double b = a * 10; double c = a + a + a + a + a + a + a + a + a + a; WriteLine(b == 1.0); WriteLine(c == 1.0); } true, true true, false false, false false, true 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 35. Ответ: С (true, false) Пояснение: Арифметика в C# реализована таким образом, что операция умножения уменьшает ошибку округления. В то же время, операция сложения только увеличивает ошибку округления. В любом случае - в лоб сравнивать числа с плавающей точкой это плохая практика.
  • 36. static void OverflowDecimal() { decimal max = decimal.MaxValue; decimal next = max + 1; WriteLine(next > max); } static void OverflowDouble() { double max = double.MaxValue; double next = max + 1; WriteLine(next == max); } true, исключение исключение, false true, true исключение, true 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 37. Ответ: D (исключение, true) Пояснение: decimal строго следит за переполнением и в случае оного выбрасывает исключение. Такое поведение не зависит от глобального флага проверки на переполнение. double реализован таким образом, что прибавление "незначительного" числа к максимуму никак учитывается. Максимум останется максимумом.
  • 38. static void Main() { decimal x = 1.0m; decimal y = 1.00m; WriteLine(x == y); WriteLine(x.ToString() == y.ToString()); } true, true true, false false, false false, true 1:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:00
  • 39. Ответ: С (true, false) Пояснение: Значения абсолютно равны. ToString выводит значение, учитывая количество разрядов после запятой.
  • 40. static class Extensions { static IEnumerable<TResult> Convert<TResult> (this IEnumerable sequence) { foreach (var item in sequence) { //it works! object runtimeItem = item; yield return (TResult) runtimeItem; } } } static void Main() { var ints = new List<int>() { 1, 2, 3, 4, 5 }; var result1 = ints.Convert<double>() .Select(x => x); var result2 = ints.Cast<double>() .Select(x => x); } сконвертит, сконвертит исключение, исключение сконвертит, исключение исключение, сконвертит 1:301:291:281:271:261:251:241:231:221:211:201:191:181:171:161:151:141:131:121:111:101:091:081:071:061:051:041:031:021:011:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:30
  • 41. Ответ: B (исключение, исключение) Пояснение: В первом случае получим InvalidCast при попытке приведения object к TResult (double). Во втором случае (.Cast<double>) в рантайме будет приведение object к double. Это вызовет InvalidCastException.
  • 42. static class Extensions { static IEnumerable<TResult> Convert<TResult> (this IEnumerable sequence) { foreach (var item in sequence) { //it works! dynamic runtimeItem = item; yield return (TResult) runtimeItem; } } } static void Main() { var ints = new List<int>() { 1, 2, 3, 4, 5 }; var result1 = ints.Convert<double>() .Select(x => x); var result2 = from c in ints select (double)c; } сконвертит, сконвертит исключение, исключение сконвертит, исключение исключение, сконвертит 1:301:291:281:271:261:251:241:231:221:211:201:191:181:171:161:151:141:131:121:111:101:091:081:071:061:051:041:031:021:011:000:590:580:570:560:550:540:530:520:510:500:490:480:470:460:450:440:430:420:410:400:390:380:370:360:350:340:330:320:310:300:290:280:270:260:250:240:230:220:210:200:190:180:170:160:150:140:130:120:110:100:090:080:070:060:050:040:030:020:01End1:30
  • 43. Ответ: A (сконвертит, сконвертит) Пояснение: В первом случае мы с помощью dynamic смотрим на рантаймовый тип, что позволяет его корректно скастовать. Во втором случае мы явно в компайл-тайме определяем тип для приведения в select. Поэтому конвертация пройдёт успешно.
  • 44. Билет на DotNext 2018 Piter (22-23 апреля) - 1 штука Билет на PHDays (15-16 мая) - 4 штуки Годовая подписка на продукты JetBrains - 3 штуки Книга Марка Симана с автографом - уникальный экземпляр Браслет Xiaomi Mi Band 2 - 1 штука + Футболка MskDotNet - 15 штук