Информация об изменениях

Сообщение Re[4]: Сложность C# приближается к С++ от 29.01.2022 16:02

Изменено 29.01.2022 16:27 Serginio1

Re[4]: Сложность C# приближается к С++
Здравствуйте, Sinclair, Вы писали:

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


S>> Ну много они добавили для увеличения скорости те же Span.

S>При этом Span<> и Async несовместимы. Ну, это ещё можно простить. Но вот Span<> и генерики несовместимы; то есть нельзя построить тип, параметризованный каким-нибудь Span<int>.
S>Так что если вы хотите описать сигнатуру "функции, которая принимает Span<char> и возвращает нужный мне тип T", то использовать Func<Span<char>, T> нельзя — надо честно писать delegate T Parse<T>(Span<char> arg):
S>
S>using System;
                    
S>public class Program
S>{
S>    public delegate T Parse<T>(ReadOnlySpan<char> span);
S>    public static void Main()
S>    {
S>        Parse<DateTime> p = (ReadOnlySpan<char> c)=>DateTime.Parse(c);
S>        Func<ReadOnlySpan<char>, DateTime> t = p; // oops!
S>    }
S>}
S>


https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/january/csharp-all-about-span-exploring-a-new-net-mainstay
В дополнение к новому конструктору string, string теперь также имеет метод Create:

public static string Create<TState>(
  int length, TState state, SpanAction<char, TState> action);
...
public delegate void SpanAction<T, in TArg>(Span<T> span, TArg arg);

Этот метод реализован для выделения строки, а затем предоставления доступного для записи промежутка, в который вы можете писать, чтобы заполнить содержимое строки во время ее создания. Обратите внимание, что в этом случае полезна только стековая природа Span<T>, гарантирующая, что span (который относится к внутреннему хранилищу строки) перестанет существовать до завершения конструктора строки, что делает невозможным использование span для изменения строки после завершения построения:

int length = ...;
Random rand = ...;
string id = string.Create(length, rand, (Span<char> chars, Random r) =>
{
  for (int i = 0; chars.Length; i++)
  {
    chars[i] = (char)(r.Next(0, 10) + '0');
  }
});

Теперь вы не только избежали выделения, но и записываете непосредственно в память строки в куче, что означает, что вы также избегаете копирования и вас не ограничивают ограничения по размеру стека.


S>>Немерлисты так долго ждали и разочаровались в Source Generator и в PM. А вот Roles http://rsdn.org/forum/dotnet/7749568.flat
Автор: varenikAA
Дата: 08.06.20
никак не введут

S>Ну, не знаю. С одной стороны, роли нафиг не нужны при наличии static abstract members в интерфейсах.
нее это как использоваие существующих операторов +,-,*,/,++, итд для алгеброических типов

S>С другой стороны, иногда хочется приклеить операторы к "чужим" типам.

S>Ну вот, скажем, если бы можно было как-то сделать B operator |(A value, Func<A, B> transform) => transform(value), то получился бы тот самый pipe operator, Math.PI | Math.Sin | Math.Cos == 1

Ну вот Roles для этого и нужны
Re[4]: Сложность C# приближается к С++
Здравствуйте, Sinclair, Вы писали:

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


S>> Ну много они добавили для увеличения скорости те же Span.

S>При этом Span<> и Async несовместимы. Ну, это ещё можно простить. Но вот Span<> и генерики несовместимы; то есть нельзя построить тип, параметризованный каким-нибудь Span<int>.
Ну стек и Async не совместимы Memory<T>
S>Так что если вы хотите описать сигнатуру "функции, которая принимает Span<char> и возвращает нужный мне тип T", то использовать Func<Span<char>, T> нельзя — надо честно писать delegate T Parse<T>(Span<char> arg):
S>
S>using System;
                    
S>public class Program
S>{
S>    public delegate T Parse<T>(ReadOnlySpan<char> span);
S>    public static void Main()
S>    {
S>        Parse<DateTime> p = (ReadOnlySpan<char> c)=>DateTime.Parse(c);
S>        Func<ReadOnlySpan<char>, DateTime> t = p; // oops!
S>    }
S>}
S>


Угу. Но наверное это тоже контроль стека!
https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/january/csharp-all-about-span-exploring-a-new-net-mainstay
В дополнение к новому конструктору string, string теперь также имеет метод Create:

public static string Create<TState>(
  int length, TState state, SpanAction<char, TState> action);
...
public delegate void SpanAction<T, in TArg>(Span<T> span, TArg arg);

Этот метод реализован для выделения строки, а затем предоставления доступного для записи промежутка, в который вы можете писать, чтобы заполнить содержимое строки во время ее создания. Обратите внимание, что в этом случае полезна только стековая природа Span<T>, гарантирующая, что span (который относится к внутреннему хранилищу строки) перестанет существовать до завершения конструктора строки, что делает невозможным использование span для изменения строки после завершения построения:

int length = ...;
Random rand = ...;
string id = string.Create(length, rand, (Span<char> chars, Random r) =>
{
  for (int i = 0; chars.Length; i++)
  {
    chars[i] = (char)(r.Next(0, 10) + '0');
  }
});

Теперь вы не только избежали выделения, но и записываете непосредственно в память строки в куче, что означает, что вы также избегаете копирования и вас не ограничивают ограничения по размеру стека.


S>>Немерлисты так долго ждали и разочаровались в Source Generator и в PM. А вот Roles http://rsdn.org/forum/dotnet/7749568.flat
Автор: varenikAA
Дата: 08.06.20
никак не введут

S>Ну, не знаю. С одной стороны, роли нафиг не нужны при наличии static abstract members в интерфейсах.
нее это как использоваие существующих операторов +,-,*,/,++, итд для алгеброических типов

S>С другой стороны, иногда хочется приклеить операторы к "чужим" типам.

S>Ну вот, скажем, если бы можно было как-то сделать B operator |(A value, Func<A, B> transform) => transform(value), то получился бы тот самый pipe operator, Math.PI | Math.Sin | Math.Cos == 1

Ну вот Roles для этого и нужны