class Type1
{
// This parameter will have an attribute (in IL) of type `IsReadOnly`public void Method1(ref readonlyint param1) { throw null; }
// This method return type will have an attribute (in IL) of type `IsReadOnly`publicref readonlyint Method2() { throw null; }
}
Зачем верхний (input) понятно, хотя может и не до конца.
А зачем нижний (return)? Туплю
Если можно пример парами — как раньше делалось и как теперь это готовить
И зачем оно в IL нужно, можно же было только си-шарпом обойтись
Здравствуйте, 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 readonlyint param1) { throw null; }
VC> // This method return type will have an attribute (in IL) of type `IsReadOnly`
VC> publicref readonlyint Method2() { throw null; }
VC>}
VC>
VC>Зачем верхний (input) понятно, хотя может и не до конца.
Я это понимаю так, как
const int *
Т.е. невозможность(неудобность) для вызываемого кода изменить значение по указателю.
VC>А зачем нижний (return)? Туплю
Ровно за тем же, но наоборот. Это неудобство для вызываемого кода изменять то, что вернул вызываемый код. Ведь он мог вернуть ссылку на свои частные требухи, которые менять нежелательно.
VC>Если можно пример парами — как раньше делалось и как теперь это готовить
с int-ом не сильно интересно. Вот ValueTuple<double, double, double> — уже может продемонстрировать накладные расходы на избыточное копирование по стеку. Вместо этого ссылка, гарантирующая неизменность, позволяет нам читать напрямую из полей класса без копирований.
VC>И зачем оно в IL нужно, можно же было только си-шарпом обойтись
C# может обеспечить неизменность в рамках C#, а что если кто-то IL запрограммирует мимо C#? Тогда никаких гарантий не выйдет.
VC>>Если можно пример парами — как раньше делалось и как теперь это готовить S>с int-ом не сильно интересно. Вот ValueTuple<double, double, double> — уже может продемонстрировать накладные расходы на избыточное копирование по стеку. Вместо этого ссылка, гарантирующая неизменность, позволяет нам читать напрямую из полей класса без копирований.
Но я бы тогда убрал слово ref совсем и оставил только readonly. И пусть компилятор(или jit) сам решает — в конкретном случае лучше скопировать, передать по ссылке, или вообще определить что из всей структуры используется только одно поле и передать его. А с ref readonly любая generic колекция будет оптимальной или нет , вдобавок куча писанины, причём коллекции с ref и без совершенно разные и по реализации и по использованию, и при этом гарантированно неоптимальность в какой-то ситуации. Увы, в команде нет капитана очевидность, так что наверное протестовать поздно, и дальше этот ёжик будет жить с нами.
P.S. И что значит зарелизила? В 15.5 preview 2 оно работает? А то в 15.4 нету такого.
Здравствуйте, hi_octane, Вы писали:
_>Но я бы тогда убрал слово ref совсем и оставил только readonly. И пусть компилятор(или jit) сам решает — в конкретном случае лучше скопировать, передать по ссылке, или вообще определить что из всей структуры используется только одно поле и передать его.
Нельзя так, семантика разная. Может передаваться массив по ссылке на элемент. И jit-у об этом не понять.
_>А с ref readonly любая generic колекция будет оптимальной или нет , вдобавок куча писанины, причём коллекции с ref и без совершенно разные и по реализации и по использованию, и при этом гарантированно неоптимальность в какой-то ситуации. Увы, в команде нет капитана очевидность, так что наверное протестовать поздно, и дальше этот ёжик будет жить с нами.
Хороший ёжик, пусть живет. С ним лучше, чем с unsafe.
Здравствуйте, VladCore, Вы писали:
VC>Вот такое 20го числа майкрософт зарелизила:
Неа. в 4.7.1 ушёл только атрибут, чтобы не возиться с нюгет-пакетами для поддержки. Всё остальное было с fw2
Всё началось с Span<T> — обёртки вокруг произвольной области памяти с индексером и без штрафа по производительности, в том числе и для получения/изменения значений обёрнутого массива (ну, или не массива).
Тут и пригодились ref return, которые вместо пары геттер/сеттер позволяют получить аналог
ref byte x = span[1];
// (псевдокод)
.ldelema array span_offset+1
Для mutable-типов тут всё очевидно, но, скажем, для строк нужен ReadOblySpan. Чтобы не было
Здравствуйте, hi_octane, Вы писали:
_>Но я бы тогда убрал слово ref совсем и оставил только readonly. И пусть компилятор(или jit) сам решает
Идея из серии "убрать class/struct/interface, пусть компилятор сам решает". Ну, т.е. при всей очевидности попытка реализации в металле неизбежно приведёт к сцене "сова и мышиёжики"
_>P.S. И что значит зарелизила? В 15.5 preview 2 оно работает? А то в 15.4 нету такого.
В c#7.2 будет.
Здравствуйте, 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?
Здравствуйте, Sinix, Вы писали:
S>P.P.S. Да, синтаксис для параметров будет in char x, не ref readonly x.
То есть теперь "char x" и "in char x" будут принципиально разными способами передачи параметров?
Первый способ как бы тоже "in" по сути.
Здравствуйте, hi_octane, Вы писали:
_>Но я бы тогда убрал слово ref совсем и оставил только readonly. И пусть компилятор(или jit) сам решает — в конкретном случае лучше скопировать, передать по ссылке, или вообще определить что из всей структуры используется только одно поле и передать его. А с ref readonly любая generic колекция будет оптимальной или нет , вдобавок куча писанины, причём коллекции с ref и без совершенно разные и по реализации и по использованию, и при этом гарантированно неоптимальность в какой-то ситуации. Увы, в команде нет капитана очевидность, так что наверное протестовать поздно, и дальше этот ёжик будет жить с нами.
Они пытаются переизобрести сишные const T&. Если оставить только readonly, то там действительно начинаются implementation-specific фокусы (кто скопирует, кто отдаст слабую ссылку и т.п.). А так чётко сказано: отдать ссылку на данные, но с доступом readonly.
Мне в этой истории больше интересно поведение GC. Будет ли он считать это слабой ссылкой (кидая исключение при попытке заюзать readonly-референс на уже задиспоженый объект) или же подобная ссылка будет продлевать время жизни объекта, способствуя замусориванию следующих поколений?
Здравствуйте, Mr.Delphist, Вы писали:
MD>Здравствуйте, hi_octane, Вы писали:
MD>Они пытаются переизобрести сишные const T&. Если оставить только readonly, то там действительно начинаются implementation-specific фокусы (кто скопирует, кто отдаст слабую ссылку и т.п.). А так чётко сказано: отдать ссылку на данные, но с доступом readonly.
как это слабую ссылку?
MD>Мне в этой истории больше интересно поведение GC. Будет ли он считать это слабой ссылкой (кидая исключение при попытке заюзать readonly-референс на уже задиспоженый объект) или же подобная ссылка будет продлевать время жизни объекта, способствуя замусориванию следующих поколений?
Т.к. нет возможностей делать ref поля, то существовать ref-ы могут лишь на стеке вызовов. Никаких проблем с GC быть не может теоретически.
Если есть ref на ссылочный тип, значит есть и сильная ссылка. Убирать ее GC никак не должен.
S>Нельзя так, семантика разная. Может передаваться массив по ссылке на элемент. И jit-у об этом не понять.
Что-то не понял что это меняет для readonly ref vs копирование при котором будет создана ещё одна ссылка на тот же самый массив. Можно пример?
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" будут слабые ссылки, то понятно что поведение обоих методов идентичное. Если же нет — то интересны подводные грабли.
Здравствуйте, Mr.Delphist, Вы писали:
MD>Если под капотом у "return ref readonly" будут слабые ссылки
Конечно не будут, лол. Вся идея (motivation) у этой фичи та, чтобы можно было эффективно (то есть без копирования) принимать/возвращать большие короткоживущие структуры (значимые типы); без привлечения аллокаций и оверхэда managed-ссылок. С реализацией через weak-ссылки (на объекты в управляемой куче) это нафиг никому не нужно.
Здравствуйте, hi_octane, Вы писали:
S>>Нельзя так, семантика разная. Может передаваться массив по ссылке на элемент. И jit-у об этом не понять. _>Что-то не понял что это меняет для readonly ref vs копирование при котором будет создана ещё одна ссылка на тот же самый массив. Можно пример?
Не понимаю, зачем джиту создавать ссылку на массив, если ему предписано вернуть ссылку на элемент массива или поле.
В том и смысл, что через ссылку можно принять/вернуть либо то, либо другое единым образом прямо в одном методе.
Здравствуйте, Mr.Delphist, Вы писали:
S>>Какая связь с ref-ом, кроме трех общих букв?
MD>Т.е. вопрос в том, будут ли 100% эквивалентны реализации этих двух методов: MD>Если под капотом у "return ref readonly" будут слабые ссылки, то понятно что поведение обоих методов идентичное. Если же нет — то интересны подводные грабли.
return ref — это примерно то же самое что и ref-parameter. Только ref-parameter — это способ передать значение по ссылке. А return ref — вернуть. Под капотом там ровно T& из C++. readonly = const модификатор на значение.
Здравствуйте, AngeL B., Вы писали:
AB>То есть теперь "char x" и "in char x" будут принципиально разными способами передачи параметров? AB>Первый способ как бы тоже "in" по сути.
Угу. И "[In] char x" для интеропа ещё. Чтобы не скучно было.
С вариантами особо не разгуляешься, т.к. нас походу ждут ещё и immutable types/variables (через два релиза, не раньше).
Но могут и поменять, если получше in-а вариант предложат.
Здравствуйте, Sinix, Вы писали:
S>Угу. И "[In] char x" для интеропа ещё. Чтобы не скучно было. S>С вариантами особо не разгуляешься, т.к. нас походу ждут ещё и immutable types/variables (через два релиза, не раньше). S>Но могут и поменять, если получше in-а вариант предложат.
Ключевое слово const, как я понимаю, пало жертвой NIH-синдрома?
Since all regular instance methods of a struct can potentially mutate the instance or ref-expose this, an intermediate copy must be created, as already a case when receiver is a readonly field.
То есть сначала сделаем readonly ref потому что не хотим копировать большие структуры, а потом делаем копию структуры на каждый вызов метода. Ну если уж взяли из плюсов константные ссылки, то и константные методы тоже берите.
S>Не понимаю, зачем джиту создавать ссылку на массив, если ему предписано вернуть ссылку на элемент массива или поле. S>В том и смысл, что через ссылку можно принять/вернуть либо то, либо другое единым образом прямо в одном методе.
Всё равно не понимаю в чём проблема. Можно всё-таки пример когда пользователь будет получать что-то неожиданное?
Моя идея в том чтобы в C# вместо readonly ref появилась конструкция "readonly T x", которая для структур (и только для них), отдавала на откуп jit'у — делать вызов через ref (если структура большая), или как обычно — через копию на стеке. Допустим на примере операции Collection<T>.IndexOf(readonly T x) where T : struct
Для структур размером с регистр — jit будет создавать копию — совсем как сейчас. А для структур весом в килобайт — сам ставить на вызов ref, так как параметр readonly для пользователя ничего не поменяется, а перфоманс выиграет.
А так как сейчас сделала ms — у коллекции надо иметь два разных метода IndexOf(T x) и IndexOf(readonly ref T x), и добавляя в структуру пару полей — надо садиться и думать, подросла ли структура достаточно чтобы бежать по проекту и менять все потенциально узкие места на readonly ref вручную.
J>То есть сначала сделаем readonly ref потому что не хотим копировать большие структуры, а потом делаем копию структуры на каждый вызов метода. Ну если уж взяли из плюсов константные ссылки, то и константные методы тоже берите.
Чем больше они делают разных readonly тем сильнее впечатление что ни у кого из авторов нет бэкграунда в C++, зато есть в JavaScript, VB и прочих питонах Лучше бы начали с const методов, пусть даже самым тупым способом — поддержав аттрибут типа решарперовского [Pure]
Здравствуйте, koandrew, Вы писали:
K>Ключевое слово const, как я понимаю, пало жертвой NIH-синдрома?
const для compile-time expressions вроде надеются заюзать. Плюс, было бы странно одно и то же понятие (неизменяемое поле / переменную) двумя кейвордами называть.
Впрочем, если есть обоснование и примеры, можно попробовать им на гитхаб написать, могут и отреагировать.
Здравствуйте, hi_octane, Вы писали:
_>Моя идея в том чтобы в C# вместо readonly ref появилась конструкция "readonly T x", которая для структур (и только для них), отдавала на откуп jit'у — делать вызов через ref (если структура большая), или как обычно — через копию на стеке. Допустим на примере операции Collection<T>.IndexOf(readonly T x) where T : struct
Без потери совместимости с текущим fw, поломки интеропа и отказа от верификации il не выйдет.
_>>Моя идея в том чтобы в C# вместо readonly ref появилась конструкция "readonly T x", которая для структур (и только для них), отдавала на откуп jit'у — делать вызов через ref (если структура большая), или как обычно — через копию на стеке. Допустим на примере операции Collection<T>.IndexOf(readonly T x) where T : struct
S>Без потери совместимости с текущим fw, поломки интеропа и отказа от верификации il не выйдет.
откуда такие страсти? даже самая топорно-хачная реализация, которую (теоретически) можно наваять пользуясь исходниками рослина — компилятору достаточно для каждого вызова IndexOf(readonly T x) генерировать ещё одну функцию с именем типа "<rref>IndexOf(readonly ref T x)", для верификатора останется щасте чистого il где все вызываются без ref если программист прямо не сказал что хочет именно с ref, и останется только подхачить jit чтобы увидев что у функции есть второй вариант вызова и он актуален — вызывать именно его. Интеропа никто ничем не касается.
Здравствуйте, hi_octane, Вы писали:
S>>Не понимаю, зачем джиту создавать ссылку на массив, если ему предписано вернуть ссылку на элемент массива или поле. S>>В том и смысл, что через ссылку можно принять/вернуть либо то, либо другое единым образом прямо в одном методе.
_>Всё равно не понимаю в чём проблема. Можно всё-таки пример когда пользователь будет получать что-то неожиданное?
Неожиданно — это потерять контроль над возможностью явного указания передачи по ссылке. Если компилятор будет внезапно генерить передачу копии, то через readonly ref char не получится передать null terminated string.
_>Моя идея в том чтобы в C# вместо readonly ref появилась конструкция "readonly T x", которая для структур (и только для них), отдавала на откуп jit'у — делать вызов через ref (если структура большая), или как обычно — через копию на стеке. Допустим на примере операции Collection<T>.IndexOf(readonly T x) where T : struct _>Для структур размером с регистр — jit будет создавать копию — совсем как сейчас. А для структур весом в килобайт — сам ставить на вызов ref, так как параметр readonly для пользователя ничего не поменяется, а перфоманс выиграет. _>А так как сейчас сделала ms — у коллекции надо иметь два разных метода IndexOf(T x) и IndexOf(readonly ref T x), и добавляя в структуру пару полей — надо садиться и думать, подросла ли структура достаточно чтобы бежать по проекту и менять все потенциально узкие места на readonly ref вручную.
Да, я вроде понял. Так вот, когда мы не знаем, скопирована ли структура, переданная в параметре, мы не можем возвращать эту структуру по ссылке.
readonly ref int Min(readonly ref int a, readonly ref int b)
{
if (a < b) return ref a;
return ref b;
}
аналогичный метод с readonly T будет просто обязан всегда возвращать копию.
Здравствуйте, hi_octane, Вы писали:
S>>Без потери совместимости с текущим fw, поломки интеропа и отказа от верификации il не выйдет. _>откуда такие страсти?
Dynamic dispatch в любой форме — делегаты, интерфейсы, DLR и т.д. Тонна ограничений типа запрета на ref return вместе с async-методами. Implicit cast из ref T в ref readonly T и тыды.
Если сильно хочется — будут ref-like structs. Со всеми ограничениями ref T, угу.
S>аналогичный метод с readonly T будет просто обязан всегда возвращать копию.
Мне что-то кажется что копирований в любом случае будет <= чем их есть сейчас. Допустим у гипотетического компилятора есть функция на одних readonly:
readonly T Min(readonly T a, readonly T b)
{
if(a.CompareTo(b) <= 0)
return a;
else
return b;
}
Проверит компилятор что от входа до выхода аттрибут "ref" сохраняется, сделает и простую версию функции, и ещё одну с входными ref и с возвращаемым значением ref. А если что-то мешает (например return default(T)) — сделает версию у которой только один аргумент с ref, или только входные с ref а возвращаемое значение без ref. И там где надо функцию вызвать — остаётся просто выбрать самую быструю из доступных сигнатур.
S>Dynamic dispatch в любой форме — делегаты, интерфейсы, DLR и т.д. Тонна ограничений типа запрета на ref return вместе с async-методами. Implicit cast из ref T в ref readonly T и тыды. S>Если сильно хочется — будут ref-like structs. Со всеми ограничениями ref T, угу.
Это всё можно поддержать, но увы, тогда придётся иметь 3 способа записи — три как сейчас с T x/ref T x/readonly ref T x, четвёртый мой — readonly T x с компилятором способным генерить 3 оставшихся. Спасибо убедил, расхотелось реально сдаюсь, причём сползаю под стол от смеха представляя как этому будут учить будущих программистов в альтернативной вселенной с "ref C#"
С одной стороны все новые возможности C# относительно структур мне нравятся — часто работаю с кодом из которого надо скорость выжать, и лучше когда варианты есть, чем когда их нет. С другой, что-то есть ощущение что лет 15 назад, когда .NET появился, я считал что идея разделить типы на reference и value гениальна, особенно после Java. А сейчас после non-nullable references, возможного интереса к stackalloc operator for reference types, и всех этих ref return, кажется что авторы языка отчаянно превозмогают косяк 15-летней давности
Здравствуйте, hi_octane, Вы писали:
S>>Dynamic dispatch в любой форме — делегаты, интерфейсы, DLR и т.д. Тонна ограничений типа запрета на ref return вместе с async-методами. Implicit cast из ref T в ref readonly T и тыды. S>>Если сильно хочется — будут ref-like structs. Со всеми ограничениями ref T, угу. _>Это всё можно поддержать, но увы, тогда придётся иметь 3 способа записи — три как сейчас с T x/ref T x/readonly ref T x, четвёртый мой — readonly T x с компилятором способным генерить 3 оставшихся. Спасибо убедил, расхотелось реально сдаюсь, причём сползаю под стол от смеха представляя как этому будут учить будущих программистов в альтернативной вселенной с "ref C#"
Всё проще. Для тех структур, которые реально требуют передачи по ref, будет модификатор ref struct и обязательный in T в параметрах методов. ref T совместимы с readonly ref T, т.е. больше ничего не требуется.
_>С одной стороны все новые возможности C# относительно структур мне нравятся — часто работаю с кодом из которого надо скорость выжать, и лучше когда варианты есть, чем когда их нет.
Ты путаешь/смешиваешь возможность оптимизации со стороны рантайма (включая инлайн, девиртуализацию, stackalloc, auto ref etc) и поддержку со стороны языка фич, которые были заложены ещё в первом CLR.
Сейчас идёт планомерная работа по второму направлению, перфоманс — по остаточному принципу. Для полноценных оптимизаций надо нарушить очень много контрактов, предлагаемых штатной CLI — раз, перейти на AOT-компиляцию — два. Ну и иметь крупного потребителя внутри MS, который протолкнёт бюджет под все доработки — три. Последнего нет, так что пока имеем net native + зачаточный AOT в net core 2.
Здравствуйте, hi_octane, Вы писали:
_>Мне что-то кажется что копирований в любом случае будет <= чем их есть сейчас. Допустим у гипотетического компилятора есть функция на одних readonly:
для мелких методов типа Min() ref не нужен. Их JIT инлайнит.
Здравствуйте, hi_octane, Вы писали:
_>Мне что-то кажется что копирований в любом случае будет <= чем их есть сейчас. Допустим у гипотетического компилятора есть функция на одних readonly: _>
_>readonly T Min(readonly T a, readonly T b)
_>{
_> if(a.CompareTo(b) <= 0)
_> return a;
_> else
_> return b;
_>}
_>
_>Проверит компилятор что от входа до выхода аттрибут "ref" сохраняется, сделает и простую версию функции, и ещё одну с входными ref и с возвращаемым значением ref. А если что-то мешает (например return default(T)) — сделает версию у которой только один аргумент с ref, или только входные с ref а возвращаемое значение без ref. И там где надо функцию вызвать — остаётся просто выбрать самую быструю из доступных сигнатур.
Хорошо, давайте рассмотрим спецификацию гипотетического языка, чей гипотетический компилятор у нас есть. И вот такой вызывающий код
var array = new []{1, 2};
ref int min = Min(ref array[0], ref array[1]); // не уверен за синтаксис
array[0] = 100;
Console.WriteLine(min);
Каким что будет на выводе согласно спецификации в случае, когда компилятор будет использовать копии и когда он будет использовать ссылки??? Будет ли результат отличаться?
И если у нас T будет не int, а что-то реально тяжелое... Т.е. int — тут на самом деле X.
S>Хорошо, давайте рассмотрим спецификацию гипотетического языка, чей гипотетический компилятор у нас есть. И вот такой вызывающий код S>
S>var array = new []{1, 2};
S>ref int min = Min(ref array[0], ref array[1]); // не уверен за синтаксис
S>array[0] = 100;
S>Console.WriteLine(min);
S>
S>Каким что будет на выводе согласно спецификации в случае, когда компилятор будет использовать копии и когда он будет использовать ссылки??? Будет ли результат отличаться?
Так array тут типа T а не "readonly T". Получается компилятор встретив Min(array[0], array[1]) сможет только копирующий вызов сделать. Впрочем я уже сдался
Здравствуйте, hi_octane, Вы писали:
S>>Каким что будет на выводе согласно спецификации в случае, когда компилятор будет использовать копии и когда он будет использовать ссылки??? Будет ли результат отличаться?
_>Так array тут типа T а не "readonly T". Получается компилятор встретив Min(array[0], array[1]) сможет только копирующий вызов сделать. Впрочем
нене, readonly T — это гарантия о том, что вызываемый код не сможет изменить значение, переданное по ссылке. Т.е. если мы будем передавать по ссылке элементы массива, то Min не сможет их изменить, даже получив ссылку. Но смогла бы, если бы получила ref int.
_>я уже сдался
, уже лучше иметь три способа дать структуру на вход, чем гадать какой из них будет использован когда ты пишешь "более простой код"
Да, чем меньше неявных манипуляций с неоднозначным результатом, тем лучше.
Здравствуйте, hi_octane, Вы писали:
_>Чем больше они делают разных readonly тем сильнее впечатление что ни у кого из авторов нет бэкграунда в C++
А чем больше я смотрю на то как они пытаются сделать из C# непонятного утконоса типа С++, тем больше мне нравится Scala.
Здравствуйте, Sinix, Вы писали:
S>Сейчас идёт планомерная работа по второму направлению, перфоманс — по остаточному принципу.
Печально, что по остаточному. Ява с ее убогой архитектурой ушла далеко вперед. МС сдает позиции.
S>Для полноценных оптимизаций надо нарушить очень много контрактов,
Не очень много. И это сделать ключиком компиляции. Такие вещи как ковариантность для массивов или множественные делегаты на практике почти не используются. Я бы с удовольствием поправил бы места где они есть (если такие вообще есть) и получил бы более высокую производительность.
S>предлагаемых штатной CLI — раз, перейти на AOT-компиляцию — два.
Что значит перейти? А куда она девалась? NGEN никто не отменял. И вообще не ясно чем тут JIT мешает. У JIT-а даже больше возможностей для оптимизации. Разве что времени мало.
S>Ну и иметь крупного потребителя внутри MS, который протолкнёт бюджет под все доработки — три. Последнего нет, так что пока имеем net native + зачаточный AOT в net core 2.
Вот как надо МС нагнуть, чтобы он начал работать на внешнего потребителя?
Людей им туда нужно новых и креативных. То что надо было делать было известно еще 10 лет назад. Когда я все это говорил надо мной тут многие потешались. Сейчас это стало даже для МС очевидно. Но можно подождать еще 10 лет и просрать все в хлам.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Людей им туда нужно новых и креативных. То что надо было делать было известно еще 10 лет назад. Когда я все это говорил надо мной тут многие потешались. Сейчас это стало даже для МС очевидно. Но можно подождать еще 10 лет и просрать все в хлам.
Всё остальное комментировать не буду, только про "новых и креативных". Не работает оно так. Или старые спецы, которые думают, затем делают, или непрекращающиеся фейлы, которые не чинятся.
Если хочется поспорить — просто поработай пару недель с net core / связанными библиотеками. Вроде всё отлично, но вечно есть один нюанс...
Типа такого (релиз библиотеки ломает авторизацию в азуре прочих библиотек от ms), такого (dotnet command не умеет в target platform), такого(ef core второй год не может работать с default values — в базу заносится мусор. И да, это не баг) или такого (с мая поломан multitargeting в студии). Это только за неделю, и то не всё. За пару месяцев стабильно три-четыре десятка багов набегает.
Что характерно, в full fw подобных ляпов как не было, так и нет (три раза по дереву). Мистика
Здравствуйте, Sinix, Вы писали:
S>Всё остальное комментировать не буду, только про "новых и креативных". Не работает оно так. Или старые спецы, которые думают, затем делают, или непрекращающиеся фейлы, которые не чинятся.
Чушь это. Не думают ни хрена. Потому и лепят костыли. Делают ошибки, потом набираются знаний и пытаются их исправить. Но тут (тадам!) совместимость!
S>Если хочется поспорить — просто поработай пару недель с net core / связанными библиотеками. Вроде всё отлично, но вечно есть один нюанс... S>Типа такого (релиз библиотеки ломает авторизацию в азуре прочих библиотек от ms), такого (dotnet command не умеет в target platform), такого(ef core второй год не может работать с default values — в базу заносится мусор. И да, это не баг) или такого (с мая поломан multitargeting в студии). Это только за неделю, и то не всё. За пару месяцев стабильно три-четыре десятка багов набегает.
Один нюанс у них был изначально. И назывался он NIH. Вместо того, чтобы воспользоваться научным и прочим опытом они все пытались сделать что-то как у други, но другое. Причем обязательно прибитое гвоздями к Виндовс. Теперь ущербность этой политики очевидна. И они вроде как по умнил. Но идут все той же дорогой.
Мне бы хотя бы 10% их ресурсов, я бы за горы свернул и Дотнет был бы лучшим продуктом на свете. А они сопли жуют и таким как ты внушают, все ОК и только так и надо.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Ну, вот. Прошли очередные 10 лет и казалось бы моя правота очевидна, но я снова вижу одни смайлики. Ну, чё? Ждите и дальше от моря погоды. Не требовать же от МС делать то что надо людям? Пусть у них "внутренний потребитель" появится.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Ну, вот. Прошли очередные 10 лет и казалось бы моя правота очевидна, но я снова вижу одни смайлики. Ну, чё? Ждите и дальше от моря погоды. Не требовать же от МС делать то что надо людям? Пусть у них "внутренний потребитель" появится.
Влад, без обид, но с тобой вообще ничего обсуждать низзя. У тебя две точки зрения, твоя и очевидно неправильная. Причём настолько "очевидно неправильная", что собеседника ты не слышишь вообще. Поэтому проще поставить смайлик и согласиться, чем спорить ради спора
Здравствуйте, VladD2, Вы писали:
VD>Один нюанс у них был изначально. И назывался он NIH. Вместо того, чтобы воспользоваться научным и прочим опытом они все пытались сделать что-то как у други, но другое. Причем обязательно прибитое гвоздями к Виндовс. Теперь ущербность этой политики очевидна. И они вроде как по умнил. Но идут все той же дорогой.
Смайлики на этом сообщении показывают, что времена меняются, но люди остаются те же. То что я вам говорил 10 лет назад для многих стало очевидным, хотя тогда тоже смайликами закидывали. К сожалению, для вас, в своей не правоте вы убедитесь, теперь, только когда на пенсию выйдете. Через 10 лет МС вам будет продавать то над чем вы смеялись сегодня. Окно Овертона действует и не в политике.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, koandrew, Вы писали:
K>Ключевое слово const, как я понимаю, пало жертвой NIH-синдрома?
Ключевое слово const — это исключительно "ваша" богомерзкая вкусовщина.
readonly говорит именно то, что оно говорит. const же подразумевает константность. При том в случае C/C++ — это от констант времени компиляции до тех же самых сигнатурных ограничений времени исполнения (т.е. на readonly). Поэтому пропихивать своё const как привыкли — это не сюда.
Нелегкая занесла столкнутся плотнячком с EF. После linq2db... не могу очиститься от EF. Я не помнимаю вообще нахрена они его сделали. Одни только строки коннекта чего стоят. Ну это так, к слову.
А ближе к теме — то мне кажется — вы оба правы (или неправы). Есть отличный н.п. сериал — называется "Титан", там рассказывается немного о том как они создавали этот модуль что высадился с Кассини на титан. Всё в слепую. А тут проще — но тока опыт помогает, в принятии решений, но "застарелый" мозг — только их отупляет. Нужна середина. А её нет ни у тебя ни у Влада, имхо. Ну и у меня нет. Все плюют со своей башни тихонько, вот и всё.
Вообще, неясно, ну блин наконец-то сделали (ли?) нормальные interior pointers — радоваться бы — да нет, всё равно что-то да не так.