Как будут различать, какой из нескольких возможных инстансов класса типов применить? Скажем, у меня в скоупе две группы — мультипилкативная и аддитивная, с одинаковым шейпом (в их примере это, скорее, моноид):
public shape SGroup<T>
{
static T Combine(T t1, T t2);
static T Identity { get; }
}
Здравствуйте, Qbit86, Вы писали:
Q>Здравствуйте, BlackEric.
Q>Как будут различать, какой из нескольких возможных инстансов класса типов применить? Скажем, у меня в скоупе две группы — мультипилкативная и аддитивная, с одинаковым шейпом (в их примере это, скорее, моноид):
Полагаю что будут требовать в точности один инстанс в скоупе, иначе ошибка компиляции. Возможно, будет способ указать инстанс шейпа явно.
Здравствуйте, BlackEric, Вы писали:
BE>Еще не успел выйти C#8, а уже пошло обсуждение 9го:
BE>Из значимого UTF8String:
эээ... с каких это пор в 21 веке нужна опять эта муита с кодировками??
Вот что реально интересно:
public class Greeter(name: string)
Наглядный пример уровня интеллекта разрабов C# — в языке десятки неуклюжестей, а им вот всралось проперть сунуть туда, куда даже дедушка не лез!
var x = ["foo":4, "bar": 5];
Наконец-то! Не прошло и 30 лет существования Перла, чтобы доблестные "переделыватели Жабы в C#" наконец додумались — в тысячах программ инициализируются словари и давно уже просился краткий, удобный синтаксис.
А вот что мне лично нехватает, так это удобнейшего паскалевскогоwith. Но видимо, макакам набирать текст привычно, так что никто не торопится это делать.
Здравствуйте, BlackEric, Вы писали:
BE>Еще не успел выйти C#8, а уже пошло обсуждение 9го:
LDT то по восьмерке уже отработал, изменений не будет. Самое время начать работать над девяткой.
BE>Из значимого UTF8String:
Оно значимое на довольно узком классе задач, а уж константы так вообще.
При этом действительно крупные фичи ты не заметил: рекорды, которые уже версии 4 никак не сделают, и шейпы, которые тянутся еще дольше.
Здравствуйте, Kolesiki, Вы писали:
K>эээ... с каких это пор в 21 веке нужна опять эта муита с кодировками??
С тех, с которых есть железки, для которых экономия на размерах сборок и ужоре памяти критична.
K>Наглядный пример уровня интеллекта разрабов C# — в языке десятки неуклюжестей, а им вот всралось проперть сунуть туда, куда даже дедушка не лез!
Здравствуйте, BlackEric, Вы писали:
BE>Еще не успел выйти C#8, а уже пошло обсуждение 9го:
BE>Candidate Features For C# 9
BE>Из значимого UTF8String: BE>
Вот востребованность дефолтового конструктора для структур не ясна, всё равно же var r = (new Rational[1])[0] поломает все инварианты. В остальном логика вроде есть.
--
updated
Но лично я бы — нафиг литералы для словаря выкинул. Где вообще логика, для в разы более часто используемого List<> нету литералов, а для словаря вот нате. Лучше бы вывод типов для generic аргументов классов завезли бы.
var dict = new Dictionary<_, _> { { "key1", 0}, { "key2", 1} };
помогло бы и словарях, и листах и еще в туче вариантов использования.
Здравствуйте, Jack128, Вы писали:
J>Вот востребованность дефолтового конструктора для структур не ясна, всё равно же var r = (new Rational[1])[0] поломает все инварианты.
Да это проще делается:
var r = default(Rational);
Вообще дефолтные конструкторы структур ранее уже добавляли в превью C# 6.0 но перед релизом откатили.
Здравствуйте, Jack128, Вы писали: J>Но лично я бы — нафиг литералы для словаря выкинул. Где вообще логика, для в разы более часто используемого List<> нету литералов
Как это нету????
J>Лучше бы вывод типов для generic аргументов классов завезли бы. J>
J>помогло бы и словарях, и листах и еще в туче вариантов использования.
Имхо, это сложно. В тривиальном случае — например, вызов конструктора — помогло бы:
class Holder
{
public static Holder<T> Create<T>(T value) => new Holder<T>(value); // костыль для type inference
}
сlass Holder<T>
{
private T _value;
public Holder(T value) => _value = value;
}
...
var h1 = Holder.Create(42); // okvar h2 = new Holder<>(42); // низзя, а можно было бы.
Но в ситуации, которая описана в вашем примере, все несколько хуже.
Сейчас компилятор трансформирует код
var dict = new XYZWUI { { "key1", 0}, { "key2", 1} };
в код
var dict = new XYZWUI();
dict.Add("key1", 0); // <- вот здесь у нас появилась информация о типах аргументов.
dict.Add("key2", 1);
Приколов тут сразу несколько.
1. Сначала нам надо научится типизировать весь блок кода, а не отдельные его строчки. То есть пытаться угадать тип-параметры в строчке 1 по типам аргументов в строчках 2 и 3.
2. Далее у нас возникают потенциальные неопределённости. Сейчас валидны обе строчки:
var d1 = new Dictionary<string, int> {{"key"}:1}
var d2 = new Dictionary<string, float> {{"key"}:1}
Нужно правило, по которому мы выберем строчку 1, увидев
var d1 = new Dictionary<,> {{"key"}:1}
3. В пользовательском типе я не обязан ограничиваться ровно 1 методом Add, сигнатура которого однозначно позволяет восстановить сигнатуру класса:
var d2 = new MyClass() { {"A", 2, 3}, { 4, 5, 6 } }; // Ok
...
public class MyClass: IEnumerable
{
public MyClass() {}
public void Add(string a, int b, double c) => Console.WriteLine($"initializing {a}={b}[{c}]");
public void Add(int a, int b, double c) => Console.WriteLine($"initializing {a}={b}[{c}]");
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
Ведь можно же и в маньяка поиграть:
var d3 = new CrazyDict<,> { {"A", 2 } }; // ??
...
public class CrazyDict<K, T>: IEnumerable
{
public CrazyDict() {}
public void Add(K key, T value) => Add((object) key, value);
public void Add(object key, object value) => Console.WriteLine($"initializing {key}={value}");
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Да ни насколько. Я в дотнете стори никогда и не перекодировал, кажется.
А в делфе постоянно проверять тип стори и кодировку приходилось, бо одна либа возвращает WideString, другая ANSI, а третья PChar какой-нибудь. Теперь это и в шарпе будет.
Y>>Насколько остра востребованность?
BE>Да ни насколько. Я в дотнете стори никогда и не перекодировал, кажется. BE>А в делфе постоянно проверять тип стори и кодировку приходилось, бо одна либа возвращает WideString, другая ANSI, а третья PChar какой-нибудь. Теперь это и в шарпе будет.
Y>?
Потому, что тип Dictionary уже есть, и это совсем не тот же самый тип, что Dictionary<,>.
Y>А лучше: Y>
Y>var dict = { { "key1", 0}, { "key2", 1} };
Y>
Ну, вот примерно это и предлагают. Только прямо такой синтаксис нельзя, т.к. по нему невозможно понять, порождать массив или словарь.
Y>Мы же понимаем так: Y>var arr = new[] { new { s = "a", i = 0 }, new { s = "b", i = 1 } };
Ну так мы это понимаем потому, что new[] гвоздями прибито к типу "массив". Алгоритм выведения типов прост, как угол дома.
А если мы захотим отодрать гвозди и сделать поддержку вот такой инициализации для произвольных типов, то придётся сильно вспотеть, т.к. взаимосвязь между типами фактических параметров и аргументами генерика неочевидна.
Y>1 — Int32 по умолчанию.
Ну, ок. В принципе, это не катастрофа (несмотря на то, что для пользовательских типов там могут быть более интересные случаи предпочтений): в простых случаях — компилируем, в сложных — падаем с ошибкой type inference.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, yenik, Вы писали:
BE>>Из значимого UTF8String: Y>Насколько остра востребованность?
Для чего понадобился UTF8String понятно.
Если в целевой системе весь ввод и вывод в utf8, это избавит от кучи лишних переконвертаций и сопутствующих накладных расходов. Очень актуально для веба.
Это можно было сделать и без вмешательства в язык, но без utf8 литералов инициализация значений выливалась бы в переконвертацию из юникода в utf8.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Jack128, Вы писали: J>>Но лично я бы — нафиг литералы для словаря выкинул. Где вообще логика, для в разы более часто используемого List<> нету литералов S>Как это нету????
Ну я такого не знаю. Есть только универсальный list-initilizer, который работает со всеми коллекциями.
J>>Лучше бы вывод типов для generic аргументов классов завезли бы. J>>
J>>помогло бы и словарях, и листах и еще в туче вариантов использования. S>Имхо, это сложно. В тривиальном случае — например, вызов конструктора — помогло бы:
Сложно или нет — могут только разрабы компилятора сказать. Сложно может быть только с точки зрения текущей архитектуры компилятора
S>Но в ситуации, которая описана в вашем примере, все несколько хуже. S>Сейчас компилятор трансформирует код S>
S>var dict = new XYZWUI();
S>dict.Add("key1", 0); // <- вот здесь у нас появилась информация о типах аргументов.
S>dict.Add("key2", 1);
S>
S>Приколов тут сразу несколько. S>1. Сначала нам надо научится типизировать весь блок кода, а не отдельные его строчки. То есть пытаться угадать тип-параметры в строчке 1 по типам аргументов в строчках 2 и 3.
Ну то есть научиться, то что компилятор сейчас уже делает в таком коде ?
var i = new[] {GetString(),GetString(),GetString()};
S>Ведь можно же и в маньяка поиграть: S>
S> var d3 = new CrazyDict<,> { {"A", 2 } }; // ??
S>...
S> public class CrazyDict<K, T>: IEnumerable
S> {
S> public CrazyDict() {}
S> public void Add(K key, T value) => Add((object) key, value);
S> public void Add(object key, object value) => Console.WriteLine($"initializing {key}={value}");
S> public IEnumerator GetEnumerator()
S> {
S> throw new NotImplementedException();
S> }
S> }
S>
Похожие вещи должны работать похоже. Алго вывода дженерик-аргументов класса должен быть таким же как и для вывода дженерик-аргументов методов.
Представь, что все дженерик-аргументы уровня класса перенесли на уровень методов:
public class CrazyDict2: IEnumerable
{
public CrazyDict() {}
public void Add<K, T>(K key, T value) => Add((object) key, value);
public void Add(object key, object value) => Console.WriteLine($"initializing {key}={value}");
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
var d3 = new CrazyDict2() { {"A", 2 } };
тут компилятор может вывести аргументы K и T. Всё, задача решена.
Нет, я прекрасно понимаю, что приспособить текущий алго под такую задачу может быть не просто, но это лучше чем тянуть специальный синтаксис для конкретно класса Dictionary<,>
Да уж лучше б операторы tolist/todict в linq query syntax запихали, пользы больше было бы.
Здравствуйте, Jack128, Вы писали:
J>Но лично я бы — нафиг литералы для словаря выкинул.
А их и выкидывают регулярно версии с 5. Но хипста-массовка негодуэ, жысончики неудобно писать.
J> Где вообще логика, для в разы более часто используемого List<> нету литералов