Задача 1: Виртуализация методов
Дан следующий код:
class A {
public virtual void Method() { Console.WriteLine("Class A"); }
}
class B : A {
public override void Method() { Console.WriteLine("Class B"); }
}
// Первый случай
A a = new B();
a.Method(); // Class B
// Второй случай
B b = new B();
b.Method(); // Class B
// Третий случай
A a1 = new B();
a1.Method(); // Class B
Вопрос: что будет выведено в консоль в каждом случае?
Разбор:
- Первый случай: Выведет «Class B». Хотя переменная имеет тип A, вызывается метод, определённый в классе B, поскольку объект, на который указывает переменная, имеет тип B. Полиморфизм позволяет вызывать версию метода, соответствующую фактическому типу объекта.
- Второй случай: Выведет «Class B». Прямой вызов переопределенного метода класса B.
- Третий случай: Выведет «Class B». Аналогично первому случаю, демонстрирует полиморфизм.
Задача 2: using и структуры
У нас есть структура C, реализующая интерфейс IDisposable:
interface IDisposable {
void Dispose();
}
struct C : IDisposable {
public bool flag;
public bool IsDisposed { get { return this.flag; } }
public void Dispose() { flag = true; }
}
Код:
using (var c = new C()) {
Console.WriteLine(c.IsDisposed); // false
}
Console.WriteLine(c.IsDisposed); // false
Вопрос: что выведется в консоль? Почему?
Ответ: false и false. Оператор using создаёт копию структуры C внутри блока. Метод Dispose() вызывается для этой копии, а не для исходной структуры. Использование IDisposable в структурах не рекомендуется из-за этого поведения.
Задача 3: Операторы инкремента
Код:
int a = 1;
Console.WriteLine(++a); // 2
int b = 1;
object obj = b;
Console.WriteLine(++b); // 2
Console.WriteLine(obj); // 1
short c = 1;
object obj1 = c;
short d = (short)obj1; // Ошибка компиляции
Вопрос: что выведется в консоль, и почему возникает ошибка?
- Первая строка: 2 (префиксный инкремент).
- Вторая строка: 2 (префиксный инкремент; obj содержит копию исходного значения b).
- Третья строка: ошибка компиляции. Неявное приведение object к short недопустимо, поскольку object содержит упакованное значение, и приведение может привести к потере данных.
Задача 4: Сравнение строк
Код:
string s1 = new string(new char[] { 'a', 'b', 'c' });
string s2 = new string(new char[] { 'a', 'b', 'c' });
Console.WriteLine(s1 == s2); // false
Вопрос: как изменить код, чтобы s1 == s2 вернуло true?
Два решения:
- Присвоить s2 ссылку на s1:
string s1 = new string(new char[] { 'a', 'b', 'c' }); string s2 = s1; Console.WriteLine(s1 == s2); // true
- Использовать литералы строк:
string s1 = "abc"; string s2 = "abc"; Console.WriteLine(s1 == s2); // true
В этом случае компилятор использует интернирование строк.
Эти вопросы помогают оценить понимание полиморфизма, работы с IDisposable, особенностей структур и операторов, а также работы со строками в C#.