Может ли C# вывести параметр Generi c при построении объекта при наличии явного ссылочного типа? - PullRequest
1 голос
/ 29 мая 2020

Java может выводить общие параметры типа c, если ссылочный тип указан явно. Например, оба из них в порядке:

Set<String> set = new HashSet<string>();
Set<String> set2 = new HashSet<>();

К сожалению, если я попытаюсь сделать что-то подобное в C#, это не будет поддерживаться:

//Doesn't compile
ISet<string> set = new HashSet<>();
//Works OK
ISet<string> set2 = new HashSet<string>();

Я получаю два компилятора сообщения в C# из приведенного выше:

CS7003 Неожиданное использование несвязанного generi c name

и

CS0266 Невозможно неявно преобразовать тип System.Collections.Generi c .HashSet в System.Collections.Generi c .ISet. Существует явное преобразование (вам не хватает приведений?)

Действительно ли эта функция не поддерживается или мне просто не хватает синтаксиса C#?

1 Ответ

0 голосов
/ 29 мая 2020

Благодаря комментарию canton7 у нас есть ответ. Эта функция (пока) не поддерживается C#, но в конвейерах обсуждается это. Есть два возможных направления, в которых это может быть принято:

Оператор Diamond <>

Предлагается использовать оператор Diamond, в точности как указано в вопросе:

https://github.com/dotnet/csharplang/issues/2935

Это позволит использовать синтаксис, подобный Java, как указано выше, где ссылочный тип - это интерфейс, а тип объекта - некоторая реализация этого интерфейса.

Новое ключевое слово

Есть предложение использовать ключевое слово new:

https://github.com/dotnet/csharplang/issues/100

Это предложение для Например, можно было бы просто заменить следующее:

Point p = new Point(1, 2);

на:

Point p = new (1, 2);

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

Hashset<string> set = new();

Сначала это кажется более действенным, чем предложение оператора ромба. Однако, возвращаясь к исходному примеру из вопроса, эта функция, если она будет разработана, не будет работать в случае, когда ссылочным типом является интерфейс. В этом случае будет непонятно, какой объект создать из new. Например, если бы мы сделали:

ISet<string> set = new ();

Тогда как компилятор узнает, какую реализацию интерфейса ISet использовать для создания экземпляра объекта этого типа? Таким образом, даже если бы эта функция была реализована, она не решила бы вариант использования, в котором ссылочным типом является интерфейс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...