Re: Params Span<T>
От: Qbit86 Кипр
Дата: 03.06.19 12:47
Оценка: +3
Здравствуйте, BlackEric, Вы писали:

BE>Востребованность остального мне пока не ясна.


Вот это офигенно же:

...params parameter-passing without any heap allocation.

void Foo(params Span<int> values);
Глаза у меня добрые, но рубашка — смирительная!
Re[4]: Concept C#: Type Classes for the Masses
От: Qbit86 Кипр
Дата: 06.06.19 14:53
Оценка: 23 (2)
Здравствуйте, Ночной Смотрящий, Вы писали:

HH>>Я так понимаю что шейпы это аналог классов типов из Haskell.

НС>Соотв. шейпы это попытка избежать их отказом от static class и введением отдельной специальной сущности. Никакой особой цели кроме как семантически связать набор статических методов с определенным типом оно не преследует.

https://github.com/MattWindsor91/roslyn/blob/master/concepts/docs/csconcepts.md
Глаза у меня добрые, но рубашка — смирительная!
Re: C# 9. Candidate Features
От: Kolesiki  
Дата: 03.06.19 11:30
Оценка: -2
Здравствуйте, BlackEric, Вы писали:

BE>Еще не успел выйти C#8, а уже пошло обсуждение 9го:


BE>Из значимого UTF8String:


эээ... с каких это пор в 21 веке нужна опять эта муита с кодировками??

Вот что реально интересно:

public class Greeter(name: string)


Наглядный пример уровня интеллекта разрабов C# — в языке десятки неуклюжестей, а им вот всралось проперть сунуть туда, куда даже дедушка не лез!

var x = ["foo":4, "bar": 5];


Наконец-то! Не прошло и 30 лет существования Перла, чтобы доблестные "переделыватели Жабы в C#" наконец додумались — в тысячах программ инициализируются словари и давно уже просился краткий, удобный синтаксис.

А вот что мне лично нехватает, так это удобнейшего паскалевского with. Но видимо, макакам набирать текст привычно, так что никто не торопится это делать.
Re[2]: C# 9. Candidate Features
От: BlackEric http://black-eric.lj.ru
Дата: 05.06.19 07:29
Оценка: -1
Здравствуйте, yenik, Вы писали:

BE>>Из значимого UTF8String:

BE>>
BE>>System.UTF8String myUTF8string ="Test String";  
BE>>


Y>Насколько остра востребованность?


Да ни насколько. Я в дотнете стори никогда и не перекодировал, кажется.
А в делфе постоянно проверять тип стори и кодировку приходилось, бо одна либа возвращает WideString, другая ANSI, а третья PChar какой-нибудь. Теперь это и в шарпе будет.
https://github.com/BlackEric001
Re[3]: C# 9. Candidate Features
От: Danchik Украина  
Дата: 05.06.19 08:23
Оценка: +1
Здравствуйте, BlackEric, Вы писали:

BE>Здравствуйте, yenik, Вы писали:


BE>>>Из значимого UTF8String:

BE>>>
BE>>>System.UTF8String myUTF8string ="Test String";  
BE>>>


Y>>Насколько остра востребованность?


BE>Да ни насколько. Я в дотнете стори никогда и не перекодировал, кажется.

BE>А в делфе постоянно проверять тип стори и кодировку приходилось, бо одна либа возвращает WideString, другая ANSI, а третья PChar какой-нибудь. Теперь это и в шарпе будет.

Кажется сделали они это чтобы без аллокаций спокойно парсить HTTP заголовки. Все для перформанса.
Вот и линка https://github.com/dotnet/corefxlab/issues/2350
Re[4]: C# 9. Candidate Features
От: HrorH  
Дата: 06.06.19 18:58
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S>C шейпами нам нужно добавить недостающие операторы или их переопределить (используя различные пространства имен как это сделано для расширений). Очень нужная конструкция.


Конструкция нужная, но операторы там не самое главное.
Один человек в одной сборке определяет класс, потом другой человек в другой сборке определяет shape. И уже после этого(!) третий человек может в третьей сборке определить, как данный класс является экземпляром этого шейпа.
То есть эта такая форма ad hoc полиморфизма, альтернативная наследованию.

В Haskell можно сразу после определения типа сказать экземпляры каких классов типов будут созданы автоматически для этого типа (это конечно возможно только для некоторых классов типов).

В примерах приводятся операторы, т.к. товарищи из Haskell (и примкнувшие к ним) очень любят алгебру: моноиды, полугруппы, монады и т.п.

Часто используются классы типов Functor, Applicative и Monad, но все они требуют нормальной системы типов, которой в C# нет.
Но даже если они сделают shape в таком виде, это будет слишком хорошо, чтобы быть правдой.
C# 9. Candidate Features
От: BlackEric http://black-eric.lj.ru
Дата: 03.06.19 10:13
Оценка:
Еще не успел выйти C#8, а уже пошло обсуждение 9го:

Candidate Features For C# 9

Из значимого UTF8String:
System.UTF8String myUTF8string ="Test String";

Востребованность остального мне пока не ясна.
https://github.com/BlackEric001
Re: Type Classes
От: Qbit86 Кипр
Дата: 03.06.19 11:00
Оценка:
Здравствуйте, BlackEric.

Как будут различать, какой из нескольких возможных инстансов класса типов применить? Скажем, у меня в скоупе две группы — мультипилкативная и аддитивная, с одинаковым шейпом (в их примере это, скорее, моноид):
public shape SGroup<T>      
{      
    static T Combine(T t1, T t2);      
    static T Identity { get; }
}
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: Type Classes
От: samius Япония http://sams-tricks.blogspot.com
Дата: 03.06.19 11:20
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, BlackEric.


Q>Как будут различать, какой из нескольких возможных инстансов класса типов применить? Скажем, у меня в скоупе две группы — мультипилкативная и аддитивная, с одинаковым шейпом (в их примере это, скорее, моноид):


Полагаю что будут требовать в точности один инстанс в скоупе, иначе ошибка компиляции. Возможно, будет способ указать инстанс шейпа явно.
Re: C# 9. Candidate Features
От: Ночной Смотрящий Россия  
Дата: 03.06.19 21:04
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>Еще не успел выйти C#8, а уже пошло обсуждение 9го:


LDT то по восьмерке уже отработал, изменений не будет. Самое время начать работать над девяткой.

BE>Из значимого UTF8String:


Оно значимое на довольно узком классе задач, а уж константы так вообще.
При этом действительно крупные фичи ты не заметил: рекорды, которые уже версии 4 никак не сделают, и шейпы, которые тянутся еще дольше.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: Type Classes
От: Ночной Смотрящий Россия  
Дата: 03.06.19 21:08
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Как будут различать, какой из нескольких возможных инстансов класса типов применить?


IMHO примерно так же, как сейчас различают extension methods.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: C# 9. Candidate Features
От: Ночной Смотрящий Россия  
Дата: 03.06.19 21:08
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>эээ... с каких это пор в 21 веке нужна опять эта муита с кодировками??


С тех, с которых есть железки, для которых экономия на размерах сборок и ужоре памяти критична.

K>Наглядный пример уровня интеллекта разрабов C# — в языке десятки неуклюжестей, а им вот всралось проперть сунуть туда, куда даже дедушка не лез!


Напиши свой язык, удиви мощью интеллекта.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: C# 9. Candidate Features
От: yenik  
Дата: 04.06.19 16:17
Оценка:
var x = new Dictionary<string, int> { { "foo", 4 } };
x = new Dictionary<string, int> { ["foo"] = 4 };
x = ["foo": 4];


Что день грядущий нам готовит?
Re: C# 9. Candidate Features
От: Jack128  
Дата: 04.06.19 19:57
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>Еще не успел выйти C#8, а уже пошло обсуждение 9го:


BE>Candidate Features For C# 9


BE>Из значимого UTF8String:

BE>
BE>System.UTF8String myUTF8string ="Test String";  
BE>

BE>Востребованность остального мне пока не ясна.

Вот востребованность дефолтового конструктора для структур не ясна, всё равно же var r = (new Rational[1])[0] поломает все инварианты. В остальном логика вроде есть.

--
updated

Но лично я бы — нафиг литералы для словаря выкинул. Где вообще логика, для в разы более часто используемого List<> нету литералов, а для словаря вот нате. Лучше бы вывод типов для generic аргументов классов завезли бы.
var dict = new Dictionary<_, _> { { "key1", 0}, { "key2", 1} };


помогло бы и словарях, и листах и еще в туче вариантов использования.
Отредактировано 04.06.2019 20:05 Jack128 . Предыдущая версия . Еще …
Отредактировано 04.06.2019 20:04 Jack128 . Предыдущая версия .
Re[2]: Default constructors
От: Qbit86 Кипр
Дата: 04.06.19 20:42
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Вот востребованность дефолтового конструктора для структур не ясна, всё равно же var r = (new Rational[1])[0] поломает все инварианты.


Да это проще делается:
var r = default(Rational);

Вообще дефолтные конструкторы структур ранее уже добавляли в превью C# 6.0 но перед релизом откатили.
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: C# 9. Candidate Features
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.19 04:20
Оценка:
Здравствуйте, Jack128, Вы писали:
J>Но лично я бы — нафиг литералы для словаря выкинул. Где вообще логика, для в разы более часто используемого List<> нету литералов
Как это нету????

J>Лучше бы вывод типов для generic аргументов классов завезли бы.

J>
J>var dict = new Dictionary<_, _> { { "key1", 0}, { "key2", 1} };
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); // ok
var 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();
        }
    }
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: C# 9. Candidate Features
От: yenik  
Дата: 05.06.19 06:07
Оценка:
J>>Лучше бы вывод типов для generic аргументов классов завезли бы.
J>>
J>>var dict = new Dictionary<_, _> { { "key1", 0}, { "key2", 1} };
J>>

Почему не
var dict = new Dictionary { { "key1", 0}, { "key2", 1} };

?
А лучше:
var dict = { { "key1", 0}, { "key2", 1} };


Мы же понимаем так:
var arr = new[] { new { s = "a", i = 0 }, new { s = "b", i = 1 } };

Тип понятен.
var s = "key1" — строка
var i = 0 — Int32

S>
S>var d1 = new Dictionary<string, int> {{"key"}:1}
S>var d2 = new Dictionary<string, float> {{"key"}:1}
S>

S>Нужно правило, по которому мы выберем строчку 1, увидев
S>
S>var d1 = new Dictionary<,> {{"key"}:1}
S>


1 — Int32 по умолчанию.
Отредактировано 05.06.2019 6:30 yenik . Предыдущая версия .
Re: C# 9. Candidate Features
От: yenik  
Дата: 05.06.19 06:21
Оценка:
BE>Из значимого UTF8String:
BE>
BE>System.UTF8String myUTF8string ="Test String";  
BE>


Насколько остра востребованность?
Re[4]: C# 9. Candidate Features
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.19 08:39
Оценка:
Здравствуйте, yenik, Вы писали:

J>>>Лучше бы вывод типов для generic аргументов классов завезли бы.

J>>>
J>>>var dict = new Dictionary<_, _> { { "key1", 0}, { "key2", 1} };
J>>>

Y>Почему не
Y>
Y>var dict = new Dictionary { { "key1", 0}, { "key2", 1} };
Y>

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.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: C# 9. Candidate Features
От: sergeya Ниоткуда http://blogtani.ru
Дата: 05.06.19 10:38
Оценка:
Здравствуйте, yenik, Вы писали:

BE>>Из значимого UTF8String:

Y>Насколько остра востребованность?

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

Это можно было сделать и без вмешательства в язык, но без utf8 литералов инициализация значений выливалась бы в переконвертацию из юникода в utf8.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[3]: C# 9. Candidate Features
От: Jack128  
Дата: 05.06.19 12:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Jack128, Вы писали:

J>>Но лично я бы — нафиг литералы для словаря выкинул. Где вообще логика, для в разы более часто используемого List<> нету литералов
S>Как это нету????
Ну я такого не знаю. Есть только универсальный list-initilizer, который работает со всеми коллекциями.

J>>Лучше бы вывод типов для generic аргументов классов завезли бы.

J>>
J>>var dict = new Dictionary<_, _> { { "key1", 0}, { "key2", 1} };
J>>

J>>помогло бы и словарях, и листах и еще в туче вариантов использования.
S>Имхо, это сложно. В тривиальном случае — например, вызов конструктора — помогло бы:
Сложно или нет — могут только разрабы компилятора сказать. Сложно может быть только с точки зрения текущей архитектуры компилятора

S>Но в ситуации, которая описана в вашем примере, все несколько хуже.

S>Сейчас компилятор трансформирует код
S>
S>var dict = new XYZWUI { { "key1", 0}, { "key2", 1} };
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 запихали, пользы больше было бы.

ЗЫ Вот прямо сейчас словари можно создавать так:

var dict = Dictionary(("val1", 1), ("val2", 2));
Re[2]: C# 9. Candidate Features
От: Ночной Смотрящий Россия  
Дата: 05.06.19 13:55
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Но лично я бы — нафиг литералы для словаря выкинул.


А их и выкидывают регулярно версии с 5. Но хипста-массовка негодуэ, жысончики неудобно писать.

J> Где вообще логика, для в разы более часто используемого List<> нету литералов


Есть для массивов потому что.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: C# 9. Candidate Features
От: Ночной Смотрящий Россия  
Дата: 05.06.19 13:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Но в ситуации, которая описана в вашем примере, все несколько хуже.

S>Сейчас компилятор трансформирует код

Это неважно во что он его трансформирует, потому что тип вывести можно и до трансформации.

S>
S>var d1 = new Dictionary<string, int> {{"key"}:1}
S>var d2 = new Dictionary<string, float> {{"key"}:1}
S>

S>Нужно правило, по которому мы выберем строчку 1, увидев
S>
S>var d1 = new Dictionary<,> {{"key"}:1}
S>


Это правило уже есть, когда ты пишешь var i = 1;
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: C# 9. Candidate Features
От: Jack128  
Дата: 05.06.19 15:49
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

J>> Где вообще логика, для в разы более часто используемого List<> нету литералов


НС>Есть для массивов потому что.

??
есть такое: var x = new[] {1,2,3}; ну это в общем тот же list-initializer только для захардкоренного типа.

есть такое: int[] y = {1,2,3};
но этот костыль вообще непонятно зачем существует (легаси времен первого шарпа?), его только вот в такой форме использовать можно.

Даже метод так нельзя вызвать
void Test(int[] arg) {}
Test({1,2,3});// ошибка компиляции.
Re[4]: C# 9. Candidate Features
От: Ночной Смотрящий Россия  
Дата: 05.06.19 18:21
Оценка:
Здравствуйте, Jack128, Вы писали:

J>есть такое: var x = new[] {1,2,3}; ну это в общем тот же list-initializer только для захардкоренного типа.


Да какая разница что там вобщем, если есть вполне компактная запись.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: C# 9. Candidate Features
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.06.19 20:09
Оценка:
Здравствуйте, BlackEric, Вы писали:
BE>Востребованность остального мне пока не ясна.

Шейпы я так понимаю, это сделать аналог С++ шаблонов c перегрузкой операторов, по аналогии с расширениями.
и солнце б утром не вставало, когда бы не было меня
Re[2]: C# 9. Candidate Features
От: HrorH  
Дата: 06.06.19 13:45
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Шейпы я так понимаю, это сделать аналог С++ шаблонов c перегрузкой операторов, по аналогии с расширениями.


Я так понимаю что шейпы это аналог классов типов из Haskell.
Но без поддержки Higher Kinded Polymorphism оно будет далеко не таким мощным как в Haskell.
Re[3]: C# 9. Candidate Features
От: Ночной Смотрящий Россия  
Дата: 06.06.19 14:44
Оценка:
Здравствуйте, HrorH, Вы писали:

HH>Я так понимаю что шейпы это аналог классов типов из Haskell.


Ну в ссылке из стартового сообщения да. Но история совсем иная. Еще с 4, еним, шарпа была идея сделать extension everything. Но она потерпела крах, слишком много конфликтов с существующим функционалом. Соотв. шейпы это попытка избежать их отказом от static class и введением отдельной специальной сущности. Никакой особой цели кроме как семантически связать набор статических методов с определенным типом оно не преследует.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: C# 9. Candidate Features
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 06.06.19 15:12
Оценка:
Здравствуйте, HrorH, Вы писали:

HH>Здравствуйте, Serginio1, Вы писали:


S>> Шейпы я так понимаю, это сделать аналог С++ шаблонов c перегрузкой операторов, по аналогии с расширениями.


HH>Я так понимаю что шейпы это аналог классов типов из Haskell.

HH>Но без поддержки Higher Kinded Polymorphism оно будет далеко не таким мощным как в Haskell.

В С++ напрополую используют перегрузку операторов в шаблонах. Для дженериков не было конструкций которые бы использовали уже существующие перегрузки операторов или которые можно было бы добавить. Проблема даже с обычными числовыми данными. Нужно добавлять интерфейс и для каждого типа добавлять Add, Div итд
C шейпами нам нужно добавить недостающие операторы или их переопределить (используя различные пространства имен как это сделано для расширений). Очень нужная конструкция.




public shape SGroup<T>      
{      
 static T operator +(T t1, T t2);      
 static T Zero {get;}       
}

This declaration says that a type can be an SGroup<T> if it implements a+ operator over T, and a Zero static property.



public extension IntGroup of int: SGroup<int>    
{    
 public static int Zero => 0;    
}


And the extension.



public static AddAll<T>(T[] ts) where T: SGroup<T> // shape used as constraint    
{    
 var result = T.Zero; // Making use of the shape's Zero property    
 foreach (var t in ts) { result += t; } // Making use of the shape's + operator    
 return result;    
}


Let us call the AddAll method with some ints,



int[] numbers = { 5, 1, 9, 2, 3, 10, 8, 4, 7, 6 };        
WriteLine(AddAll(numbers)); // infers T = int
и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.