Вопросы по C# и ответы на них

1. Поддерживает ли C# множественное наследование?
Нет. Но можно реализовать с помощью паттерна:

public interface IFirst { void FirstMethod(); }
public interface ISecond { void SecondMethod(); }

public class First:IFirst 
{ 
    public void FirstMethod() { Console.WriteLine("First"); } 
}

public class Second:ISecond 
{ 
    public void SecondMethod() { Console.WriteLine("Second"); } 
}

public class FirstAndSecond: IFirst, ISecond
{
    First first = new First();
    Second second = new Second();
    public void FirstMethod() { first.FirstMethod(); }
    public void SecondMethod() { second.SecondMethod(); }
}
2. Существует ли базовый тип объекта, от которого все наследуются? Если да, то как он называется?
Да. System.Object.

3. Какие коллекции в C# вы знаете?

std::vector - List, ArrayList

std::list - LinkedList
std::map - Dictionary
std::set - HashSet
std::multimap - Dictionary>, HashTable
std::queue - Queue
std::stack - Stack

Специализированные

ListDictionary
HybridDictionary
SortedDictionary
StringDictionary
NameValueCollection
DictionaryEntry
ConcurrentDictionary

3. Какие коллекции в C# позволяет доступаться к элементам по уникальному ключу?
HashTable, Dictionary

4. Будет ли блок finally выполнен, если исключение не будет выброшено?

В блоке finally вы можете освободить ресурсы, которые вы выделили в блоке try. И вы можете запустить код, даже если исключение было выброшено в блоке try. Обычно, код блока finally запускается, когда выполнение программы покидает try секцию. Передача контроля может осуществиться как результат нормального выполнения. Если исключение было поймано, то finally гарантированно выполнится. Однако, если исключение не было поймано, то выполнение блока finally зависит от того, как запустится операция раскрутки стека. Это, в свою очередь, зависит от того, как настроен ваш компьютер (CLR).
Ответ - да, этот блок будет выполнен.


5. Что такое делегат?

Делегат в C# - это сущность, похожая на указатель на функцию в C/C++. Использование делегатов позволяет разработчику инкапсулировать ссылку на метод внутри делегата. После этого делегат может быть передан в код, который вызывает этот метод, при этом он не знает во время компиляции, какой именно метод будет вызван. В отличие от указателей на функции в C/C++, делегаты являются объектно-ориентированными, безопасными и типизированными.

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

Интересная особенность делегатов - это то, что делегаты ничего не знают о классе и об объекте, на который они ссылаются. Это делает делегаты хорошо подходящими для "анонимных" вызовов.

// Создать делегат
public delegate void ProcessCarDelegate(Car co);

// Инстанциировать и использовать метод Repair с аргументом Car.
// Получается неважно, какой объект или функция это. Главное,
// чтобы она принимала  в качестве аргумента объект типа Car.
carReparationFacility.RepairBrokenCars(new ProcessCarDelegate(Repair));

6. Можно ли определить несколько catch блоков для одного блока try?
Да.

7. Можно ли сделать так, чтобы несколько блоков catch были выполнены для одного блока try?
Да. Делать rethrow.

8. Как определить класс, от которого нельзя наследоваться?
Объявить его как sealed.

9. В каком случае вы обязательно должны объявить класс абстрактным? Существует два правильных ответа.

10. Поддерживает ли .NET множественное наследование интерфейсов?
Да.

11. В чем отличие интерфейса от абстрактного класса?
Здесь хорошо написано: http://www.codeproject.com/Articles/11155/Abstract-Class-versus-Interface

Особенность Интерфейс Абстрактный класс
Множ.насл. [Да] [Нет]
Реализация методов по умолч [Нет] [Да]
Скорость работы [Быстрый] [Время на поиск метода соответствующего класса]
Добавление функциональности [Нужно переопределять метод во всех потомках] [Можно использовать реализацию по умолчанию]
Поля и константы [Нет] [Да]

12. Что обозначает ключевое слово virtual для свойства или метода?
Обозначает, что это свойство или метод может быть переопределен позже с помощью override.

13. Чем объявление метода как virtual отличается от abstract?
Тем, что если объявление virtual, то метод нужно определять. А если abstract - то нет.

14. В чем разница между переопределением метода и его перегрузкой?
В том что переопределение - это реализация полиморфизма. А перегрузка - это создание функции с тем же именем, но с другими параметрами.

15. Для нужны модификаторы ref и out у аргументов функции (или метода)?
ref - объект возвращается по ссылке, при этом не создается его копия
out - то же самое что и ref, только нет необходимости инициализировать переменную перед тем, как передавать её в функцию.

16. Для чего нужен модификатор params?
Он позволяет не создавать массив переменных перед тем, как передавать его в функцию, а писать их по порядку.
Например void f(params string[] lines) позволит вызвать функцию f следующим образом f("Abc", "Def", "Ghi").

17. Можно ли установить разные модификаторы доступа (public/private) для get и set методов свойства?
Да.
class MyClass
{
  private int pa = 0;
  public int a
  {
    get
    {
      return pa;
    }
    private set
    {
      pa = value;
    }
  }
}

18. Что такое индексатор?
Это класс, с определенным в нем оператором []. Пример.
class MyClass
{
  private string[] range = new string[5];
  public string this[int idx]
  {
    get
    {
      return range[idx];
    }
    set
    {
      range[idx] = value;
    }
  }
}

19. В чем отличие System.Text.StringBuilder от System.String?
StringBuilder - эффективнее, если со строками производится много манипуляций. Каждый раз, когда производится операция над String, создается новая копия.

20. Можно ли хранить в System.Array данные разных типов?
Нет. System.Array - строго типизирован.

21. В чем разница между System.Array.CopyTo() и System.Array.Clone()?
Первый производит глубокое копирование. Второй - тривиальное.

22. Как отсортировать элементы массива в убывающем порядке?
Sort().Reverse();

23. Что такое мультикаст делегат?
Это обычный делегат, который привязывается к нескольким функциям.
Например:

public void delegate MyDelegate(int i);

class A
{
public void foo1(int i) { Console.WriteLine("A::foo1(" + i + ")"); }
}

class B
{
public void foo2(int i) { Console.WriteLine("B::foo2(" + i + ")"); }
}

class Program
{
  static void Main(string[] args)
  {
    A a = new A();
    B b = new B();
    MyDelegate d = new MyDelegate(a.foo1);
    d += b.foo2;
  }
}

24. В чем отличие структуры от класса в C#?
Структура создается на стеке. Класс - в куче.

* В объявлении структуры поля не могут быть инициализированы до тех пор, пока они будут объявлены как постоянные или статические.
* Структура не может объявлять используемый по умолчанию конструктор (конструктор без параметров) или деструктор.
* Структуры копируются при присваивании. При присваивании структуры к новой переменной выполняется копирование всех данных, а любое изменение новой копии не влияет на данные в исходной копии. Это важно помнить при работе с коллекциями типов значений, такими как Dictionary.
* Структуры являются типами значений, а классы — ссылочными типами.
* В отличие от классов, структуры можно создавать без использования оператора new.
* Структуры могут объявлять конструкторы, имеющие параметры.
* Структура не может быть унаследованной от другой структуры или класса и не может быть основой для других классов. Все структуры наследуют непосредственно от System.ValueType, который наследует от System.Object.
* Структуры могут реализовывать интерфейсы.
* Структура может использоваться как тип, допускающий значение NULL, и ей можно назначить значение NULL.

25. Что такое Action?
Action - это неименованный параметризированный делегат. Используется в лямбда выражениях.
Объекты Action не возвращают значений. Тип Action в C# похож на метод void. Он никогда не возвращает значение.


Action a1 = () => Console.Write(1);
Action a2 = () => Console.Write(2);
Action a3 = () => Console.Write(3);
((a1 + a2 + a3) - (a1 + a2))();
((a1 + a2 + a3) - (a1 + a3))();

Action a4 = (x) => Console.Write(x);
a4.Invoke(5);

Action поддерживается начиная с версии .NET 3.5.

26. Что такое event?
event - это модификатор для делегата. Делегат с таким модификатором является потокобезопасным и может быть определен в интерфейсе. Однако, вызываться этот event может только из того класса, где он определен.

27. Что такое правила "ACID" для транзакций в базе данных?
* Atomic - it is one unit of work and does not dependent on previous and following transactions.
* Consistent - data is either committed or roll back, no "in-between" case where something has been updated and something hasn't.
* Isolated - no transaction sees the intermediate results of the current transaction.
* Durable - the values persist if the data had been committed even if the system crashes right after.

28. Какие пространства имен необходимы для создания локализованного приложения?
System.Globalization, System.Resources.

29. В чем разница между delegate и event?
См. вопрос 26.

30. Что такое частично определенный класс? В чем его преимущества?
Частично определенный класс позволяет определить код в разных файлах. Этим и удобен.

31. В чем разница между глубоким копированием и обычным?
В том, что при обычном копировании объекта создается копии ссылок на один и тот же объект. А при глубоком все ссылки инициализируются своими собственными объектами.

32. Какой синоним у типа int?
System.Int32.

33. Как можно определить двумерный массив в C#?

34. Что такое упаковка (boxing) в C#?
Это приведение value объекта к типу Object.

35. Чем отличается a.Equals(b) от a == b?
Для ссылочных типов "==" проверяет равенство ссылок. Equals проверяет равенство объектов, на которые указывают ссылки.

36. Что означает protected internal доступ?
Если поле или метод класса А объявляется с модификатором доступа protected internal, это означает, что это поле или метод доступны в классах наследниках (неважно где он вызывается), а также внутри текущего модуля.

37. В чем разница между классом Debug и классом Trace?

38. Как реализовать упаковку самому?


    class Boxing where T : struct
    {
        private T data;
        public Boxing(T _val)
        {
            data = _val;
        }

        public override string ToString()
        {
            return data.ToString();
        }

        public static explicit operator T(Boxing str)
        {
            return str.data;
        }
    }

39. Какие методы в System.Object реализуют механизм хеширования?
GetHashCode и Equals.

40. Для чего нужен Equals и GetHashCode?
Для добавления объекта в контейнеры типа Dictionary. Этот контейнер - хэш-таблица. В ней ограниченное количество корзин. Поэтому GetHashCode на разных объектах может возвратить одно значение. Однако Equals для них должен быть false. Если Equals возвращает true, то GetHashCode тоже должен вернуть одинаковые значения.

41.

Comments

Unknown said…
17. Можно ли установить разные модификаторы доступа (public/private) для get и set методов свойства?
Нет.
На самом деле можно. Класс class MyClass
{
private int pa = 0;
public int a
{
get
{
return pa;
}
private set
{
pa = value;
}
}
}
вполне компилируется. В книге Шилдта даже описывается возможность создания кратких свойств типа int p{get; private set;} - это свойство, которое можно изменять только из самого класса, а снаружи оно доступно только для чтения. Подобным образом реализуется Array.Length

Popular Posts