C# почему так лучше не делать?


#1

Почему не рекомендуется следующая форма записи:
IntList : List<int> {}

А желательно писать:
using IntList = System.Collections.Generic.List;

Я просто хочу у себя в проекте создавать коллекций сразу закрытых типом int.


#2

Потому что такую форму записи IntList : List<int> {} C# не поддерживает совсем на синтаксическом уровне.
Дальше вы подмешиваете понятия пространства имен в которых доступна структура данных List и создание экземпляра данной структуры данных (список).
Для того чтобы создать экземпляр списка параметризированной типом int нужно прописать в месте где планируется использоваться данная структура данных: List<int> nameYouCollection = new List<int>(); при этом не забыв подключить пространство имен System.Collection.Generic.


#3

я немного не то написал:

  1. не IntList : List<int> {}, а class IntList : List<int> { } (ошибки с поддержанием нету)
  2. пропустил закрытие using IntList = System.Collections.Generic.List<int>;

#4

Рихтер подымал эту тему у себя в книге и писал следующее:

Синтаксис обобщенных типов часто приводит разработчиков в замешательство.
В исходном коде появляется слишком много знаков «меньше» (<) и «больше» (>), и это сильно затрудняет его чтение. Для упрощения синтаксиса некоторые разработчики определяют новый не обобщенный тип класса, производный от обобщенного типа и определяющий все необходимые аргументы типа. Например, пусть нужно упростить следующий код:

List<DateTime> dt = new List<DateTime>();

Некоторые разработчики сначала определят класс:

internal sealed class DateTimeList : List<DateTime> {
 // Здесь никакой код добавлять не нужно!
}

Теперь код создания списка можно написать проще (без знаков < и >):

DateTimeList dt = new DateTimeList();

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

Boolean sameType = (typeof(List<DateTime>) == typeof(DateTimeList));

При выполнении этого кода sameType инициализируется значением false, потому что сравниваются два объекта разных типов. Это также значит, что методу, в прототипе которого определено, что он принимает значение типа DateTimeList, нельзя передать List. Тем не менее методу, который должен принимать List, можно передать DateTimeList, потому что тип DateTimeList является производным от List. Запутаться в этом очень просто.
К счастью, C# позволяет использовать упрощенный синтаксис для ссылки на обобщенный закрытый тип, не влияющий на эквивалентность типов. Для этого в начало файла с исходным текстом нужно добавить старую добрую директиву using:

using DateTimeList = System.Collections.Generic.List<System.DateTime>;

Здесь директива using просто определяет символическое имя DateTimeList. При компиляции кода компилятор заменяет все вхождения DateTimeList типом System.Collections.Generic.List<System.DateTime>. Таким образом, разработчики могут использовать упрощенный синтаксис, не меняя смысл кода и тем самым сохраняя идентификацию и тождество типов. Теперь при выполнении следующей строки кода sameType инициализируется значением true:

Boolean sameType = (typeof(List<DateTime>) == typeof(DateTimeList));

Для удобства вы можете использовать свойство локальной переменной неявного типа языка C#, для которой компилятор обозначает тип локальной переменной метода из типа вашего выражения:

using System;
using System.Collections.Generic;
...
internal sealed class SomeType {
 private static void SomeMethod () {
 // Компилятор определяет, что dtl имеет тип
 // System.Collections.Generic.List<System.DateTime>
 var dtl = List<DateTime>();
 ...
 }
}