Новый ref readonly в C# & IL
От: VladCore  
Дата: 23.10.17 19:53
Оценка:
Вот такое 20го числа майкрософт зарелизила:

class Type1
{
    // This parameter will have an attribute (in IL) of type `IsReadOnly`
    public void Method1(ref readonly int param1) { throw null; }

    // This method return type will have an attribute (in IL) of type `IsReadOnly`
    public ref readonly int Method2() { throw null; }
}


Зачем верхний (input) понятно, хотя может и не до конца.

А зачем нижний (return)? Туплю

Если можно пример парами — как раньше делалось и как теперь это готовить

И зачем оно в IL нужно, можно же было только си-шарпом обойтись
Отредактировано 23.10.2017 19:59 VladCore . Предыдущая версия . Еще …
Отредактировано 23.10.2017 19:58 VladCore . Предыдущая версия .
Отредактировано 23.10.2017 19:55 VladCore . Предыдущая версия .
Re: Новый ref readonly в C# & IL
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.10.17 21:44
Оценка: +4
Здравствуйте, VladCore, Вы писали:

VC>Вот такое 20го числа майкрософт зарелизила:


VC>
VC>class Type1
VC>{
VC>    // This parameter will have an attribute (in IL) of type `IsReadOnly`
VC>    public void Method1(ref readonly int param1) { throw null; }

VC>    // This method return type will have an attribute (in IL) of type `IsReadOnly`
VC>    public ref readonly int Method2() { throw null; }
VC>}
VC>


VC>Зачем верхний (input) понятно, хотя может и не до конца.

Я это понимаю так, как
const int *

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

VC>А зачем нижний (return)? Туплю

Ровно за тем же, но наоборот. Это неудобство для вызываемого кода изменять то, что вернул вызываемый код. Ведь он мог вернуть ссылку на свои частные требухи, которые менять нежелательно.

VC>Если можно пример парами — как раньше делалось и как теперь это готовить

с int-ом не сильно интересно. Вот ValueTuple<double, double, double> — уже может продемонстрировать накладные расходы на избыточное копирование по стеку. Вместо этого ссылка, гарантирующая неизменность, позволяет нам читать напрямую из полей класса без копирований.

VC>И зачем оно в IL нужно, можно же было только си-шарпом обойтись

C# может обеспечить неизменность в рамках C#, а что если кто-то IL запрограммирует мимо C#? Тогда никаких гарантий не выйдет.
Re[2]: Новый ref readonly в C# & IL
От: hi_octane Беларусь  
Дата: 24.10.17 00:00
Оценка: :)
VC>>Если можно пример парами — как раньше делалось и как теперь это готовить
S>с int-ом не сильно интересно. Вот ValueTuple<double, double, double> — уже может продемонстрировать накладные расходы на избыточное копирование по стеку. Вместо этого ссылка, гарантирующая неизменность, позволяет нам читать напрямую из полей класса без копирований.

Но я бы тогда убрал слово ref совсем и оставил только readonly. И пусть компилятор(или jit) сам решает — в конкретном случае лучше скопировать, передать по ссылке, или вообще определить что из всей структуры используется только одно поле и передать его. А с ref readonly любая generic колекция будет оптимальной или нет , вдобавок куча писанины, причём коллекции с ref и без совершенно разные и по реализации и по использованию, и при этом гарантированно неоптимальность в какой-то ситуации. Увы, в команде нет капитана очевидность, так что наверное протестовать поздно, и дальше этот ёжик будет жить с нами.

P.S. И что значит зарелизила? В 15.5 preview 2 оно работает? А то в 15.4 нету такого.
Re[3]: Новый ref readonly в C# & IL
От: VladCore  
Дата: 24.10.17 04:03
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>P.S. И что значит зарелизила? В 15.5 preview 2 оно работает? А то в 15.4 нету такого.


.NET Framework скачать уже можно. В студии 2017.5 только будет
Re[3]: Новый ref readonly в C# & IL
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.10.17 04:22
Оценка: +1
Здравствуйте, hi_octane, Вы писали:

_>Но я бы тогда убрал слово ref совсем и оставил только readonly. И пусть компилятор(или jit) сам решает — в конкретном случае лучше скопировать, передать по ссылке, или вообще определить что из всей структуры используется только одно поле и передать его.

Нельзя так, семантика разная. Может передаваться массив по ссылке на элемент. И jit-у об этом не понять.

_>А с ref readonly любая generic колекция будет оптимальной или нет , вдобавок куча писанины, причём коллекции с ref и без совершенно разные и по реализации и по использованию, и при этом гарантированно неоптимальность в какой-то ситуации. Увы, в команде нет капитана очевидность, так что наверное протестовать поздно, и дальше этот ёжик будет жить с нами.

Хороший ёжик, пусть живет. С ним лучше, чем с unsafe.
Re: Новый ref readonly в C# & IL
От: Sinix  
Дата: 24.10.17 06:48
Оценка: 40 (5) +2
Здравствуйте, VladCore, Вы писали:

VC>Вот такое 20го числа майкрософт зарелизила:


Неа. в 4.7.1 ушёл только атрибут, чтобы не возиться с нюгет-пакетами для поддержки. Всё остальное было с fw2

Всё началось с Span<T> — обёртки вокруг произвольной области памяти с индексером и без штрафа по производительности, в том числе и для получения/изменения значений обёрнутого массива (ну, или не массива).
Тут и пригодились ref return, которые вместо пары геттер/сеттер позволяют получить аналог
ref byte x = span[1];
// (псевдокод)
.ldelema array span_offset+1

Для mutable-типов тут всё очевидно, но, скажем, для строк нужен ReadOblySpan. Чтобы не было
ref char x = stringSpan[1];
x = 'X'; // oops

Детали см тут.

P.S. Ну и разумеется, с великой мощью приходит и новый способ взорвать всё к чертям, куда ж без этого

P.P.S. Да, синтаксис для параметров будет in char x, не ref readonly x.
Re[3]: Новый ref readonly в C# & IL
От: Sinix  
Дата: 24.10.17 06:55
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Но я бы тогда убрал слово ref совсем и оставил только readonly. И пусть компилятор(или jit) сам решает

Идея из серии "убрать class/struct/interface, пусть компилятор сам решает". Ну, т.е. при всей очевидности попытка реализации в металле неизбежно приведёт к сцене "сова и мышиёжики"

_>P.S. И что значит зарелизила? В 15.5 preview 2 оно работает? А то в 15.4 нету такого.

В c#7.2 будет.
Re: Новый ref readonly в C# & IL
От: AngeL B. Россия  
Дата: 24.10.17 13:40
Оценка:
Здравствуйте, VladCore, Вы писали:

VC>[cs]

VC>class Type1
VC>{
VC> // This parameter will have an attribute (in IL) of type `IsReadOnly`
VC> public void Method1(ref readonly int param1) { throw null; }

Зачем это надо, как раз не вопрос. У меня вопрос проще, почему readonly а не const?
Re[2]: Новый ref readonly в C# & IL
От: AngeL B. Россия  
Дата: 24.10.17 13:46
Оценка:
Здравствуйте, Sinix, Вы писали:

S>P.P.S. Да, синтаксис для параметров будет in char x, не ref readonly x.

То есть теперь "char x" и "in char x" будут принципиально разными способами передачи параметров?
Первый способ как бы тоже "in" по сути.
Re[3]: Новый ref readonly в C# & IL
От: Mr.Delphist  
Дата: 24.10.17 15:03
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Но я бы тогда убрал слово ref совсем и оставил только readonly. И пусть компилятор(или jit) сам решает — в конкретном случае лучше скопировать, передать по ссылке, или вообще определить что из всей структуры используется только одно поле и передать его. А с ref readonly любая generic колекция будет оптимальной или нет , вдобавок куча писанины, причём коллекции с ref и без совершенно разные и по реализации и по использованию, и при этом гарантированно неоптимальность в какой-то ситуации. Увы, в команде нет капитана очевидность, так что наверное протестовать поздно, и дальше этот ёжик будет жить с нами.


Они пытаются переизобрести сишные const T&. Если оставить только readonly, то там действительно начинаются implementation-specific фокусы (кто скопирует, кто отдаст слабую ссылку и т.п.). А так чётко сказано: отдать ссылку на данные, но с доступом readonly.

Мне в этой истории больше интересно поведение GC. Будет ли он считать это слабой ссылкой (кидая исключение при попытке заюзать readonly-референс на уже задиспоженый объект) или же подобная ссылка будет продлевать время жизни объекта, способствуя замусориванию следующих поколений?
Re[4]: Новый ref readonly в C# & IL
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.10.17 15:09
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

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


MD>Они пытаются переизобрести сишные const T&. Если оставить только readonly, то там действительно начинаются implementation-specific фокусы (кто скопирует, кто отдаст слабую ссылку и т.п.). А так чётко сказано: отдать ссылку на данные, но с доступом readonly.

как это слабую ссылку?

MD>Мне в этой истории больше интересно поведение GC. Будет ли он считать это слабой ссылкой (кидая исключение при попытке заюзать readonly-референс на уже задиспоженый объект) или же подобная ссылка будет продлевать время жизни объекта, способствуя замусориванию следующих поколений?

Т.к. нет возможностей делать ref поля, то существовать ref-ы могут лишь на стеке вызовов. Никаких проблем с GC быть не может теоретически.
Если есть ref на ссылочный тип, значит есть и сильная ссылка. Убирать ее GC никак не должен.
Re[5]: Новый ref readonly в C# & IL
От: Mr.Delphist  
Дата: 24.10.17 15:55
Оценка:
Здравствуйте, samius, Вы писали:

S>как это слабую ссылку?

https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx

Represents a weak reference, which references an object while still allowing that object to be reclaimed by garbage collection.

Re[6]: Новый ref readonly в C# & IL
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.10.17 16:03
Оценка: +1
Здравствуйте, Mr.Delphist, Вы писали:

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


S>>как это слабую ссылку?

MD>https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx
MD>

MD>Represents a weak reference, which references an object while still allowing that object to be reclaimed by garbage collection.

Какая связь с ref-ом, кроме трех общих букв?
Re[4]: Новый ref readonly в C# & IL
От: hi_octane Беларусь  
Дата: 24.10.17 17:14
Оценка:
S>Нельзя так, семантика разная. Может передаваться массив по ссылке на элемент. И jit-у об этом не понять.
Что-то не понял что это меняет для readonly ref vs копирование при котором будет создана ещё одна ссылка на тот же самый массив. Можно пример?
Re[7]: Новый ref readonly в C# & IL
От: Mr.Delphist  
Дата: 24.10.17 17:48
Оценка:
Здравствуйте, samius, Вы писали:

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


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


S>>>как это слабую ссылку?

MD>>https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx
MD>>

MD>>Represents a weak reference, which references an object while still allowing that object to be reclaimed by garbage collection.

S>Какая связь с ref-ом, кроме трех общих букв?

Т.е. вопрос в том, будут ли 100% эквивалентны реализации этих двух методов:
class Type1
{
    private int _myInt = 42;

    // This method return type will have an attribute (in IL) of type `IsReadOnly`
    public ref readonly int Method2() { return ref this._myInt; }
    public WeakReference<int> OldSchoolMethod2() { return new WeakReference<int>(this._myInt); }
}

...

var t = new Type1();
ref int x = t.Method2(); // будет ли это влиять на GC?
WeakReference<int> y = t.OldSchoolMethod2(); // потому что это - не должно (y.Target==null после сборки мусора)


Если под капотом у "return ref readonly" будут слабые ссылки, то понятно что поведение обоих методов идентичное. Если же нет — то интересны подводные грабли.
Re[8]: Под капотом
От: Qbit86 Кипр
Дата: 24.10.17 18:03
Оценка: +1
Здравствуйте, Mr.Delphist, Вы писали:

MD>Если под капотом у "return ref readonly" будут слабые ссылки


Конечно не будут, лол. Вся идея (motivation) у этой фичи та, чтобы можно было эффективно (то есть без копирования) принимать/возвращать большие короткоживущие структуры (значимые типы); без привлечения аллокаций и оверхэда managed-ссылок. С реализацией через weak-ссылки (на объекты в управляемой куче) это нафиг никому не нужно.
Глаза у меня добрые, но рубашка — смирительная!
Re[5]: Новый ref readonly в C# & IL
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.10.17 18:17
Оценка:
Здравствуйте, hi_octane, Вы писали:

S>>Нельзя так, семантика разная. Может передаваться массив по ссылке на элемент. И jit-у об этом не понять.

_>Что-то не понял что это меняет для readonly ref vs копирование при котором будет создана ещё одна ссылка на тот же самый массив. Можно пример?
Не понимаю, зачем джиту создавать ссылку на массив, если ему предписано вернуть ссылку на элемент массива или поле.
В том и смысл, что через ссылку можно принять/вернуть либо то, либо другое единым образом прямо в одном методе.
Re[8]: Новый ref readonly в C# & IL
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.10.17 18:21
Оценка: 1 (1)
Здравствуйте, Mr.Delphist, Вы писали:

S>>Какая связь с ref-ом, кроме трех общих букв?


MD>Т.е. вопрос в том, будут ли 100% эквивалентны реализации этих двух методов:

MD>Если под капотом у "return ref readonly" будут слабые ссылки, то понятно что поведение обоих методов идентичное. Если же нет — то интересны подводные грабли.

return ref — это примерно то же самое что и ref-parameter. Только ref-parameter — это способ передать значение по ссылке. А return ref — вернуть. Под капотом там ровно T& из C++. readonly = const модификатор на значение.
Re[3]: Новый ref readonly в C# & IL
От: Sinix  
Дата: 24.10.17 19:22
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>То есть теперь "char x" и "in char x" будут принципиально разными способами передачи параметров?

AB>Первый способ как бы тоже "in" по сути.

Угу. И "[In] char x" для интеропа ещё. Чтобы не скучно было.
С вариантами особо не разгуляешься, т.к. нас походу ждут ещё и immutable types/variables (через два релиза, не раньше).
Но могут и поменять, если получше in-а вариант предложат.
Re[2]: Новый ref readonly в C# & IL
От: sergeya Ниоткуда http://blogtani.ru
Дата: 24.10.17 20:20
Оценка: +1
Здравствуйте, AngeL B., Вы писали:

AB>Зачем это надо, как раз не вопрос. У меня вопрос проще, почему readonly а не const?


const означало бы, что значение никогда не меняется, что не факт.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.