Здравствуйте, Sinclair, Вы писали:
ARK>>Не надо никаких by default. Уже есть классы и структуры. S> Отличная тактика. Если спорол чушь, то не надо признавать это — надо тут же спороть другую чушь, чтобы отвлечь собеседников от чуши предыдущей. S>Продолжайте, мне сейчас курьер пакет попкорна должен привезти.
Какая еще "чушь", "тактика", але. Негрософт сделал очередное мутабельное говно, впридачу к двум существующим. То, что оно иммутабельно по умолчанию — совершенно ничего не значит, такие "иммутабельные" классы и сейчас делать можно.
Впрочем, реакция сектантов совершенно предсказуема, я об этом сразу и написал.
Здравствуйте, AlexRK, Вы писали: ARK>Какая еще "чушь", "тактика", але.
Действительно, какая тут тактика. Прошу прощения, я ошибся. Тут только метание говна, без тактики и стратегии. ARK>Негрософт сделал очередное мутабельное говно, впридачу к двум существующим. То, что оно иммутабельно по умолчанию — совершенно ничего не значит, такие "иммутабельные" классы и сейчас делать можно. ARK>Впрочем, реакция сектантов совершенно предсказуема, я об этом сразу и написал.
Мне всё же интересно — можете проиллюстрировать "проблему" кодом?
Ну, то есть полезность рекордов проиллюстрировать кодом легко — например, можно тупо нарисовать иерархию классов System.Linq.Expression и сравнить объём кода на "и сейчас делать можно" с объёмом кода на рекордах.
Покажите, какой именно сценарий вы хотите написать на рекордах, и вам не удаётся из-за того, что это "очередное мутабельное говно".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
ARK>>Какая еще "чушь", "тактика", але. S>Действительно, какая тут тактика. Прошу прощения, я ошибся. Тут только метание говна, без тактики и стратегии.
Не, ну необоснованно обвинять меня в какой-то там невнимательности — это тоже тактика так себе. В статье по ссылке вообще мутабельность никак не педалируется. Чтобы понять, что рекорды мутабельные, надо как раз наоборот быть внимательным.
S>Мне всё же интересно — можете проиллюстрировать "проблему" кодом? S>Ну, то есть полезность рекордов проиллюстрировать кодом легко — например, можно тупо нарисовать иерархию классов System.Linq.Expression и сравнить объём кода на "и сейчас делать можно" с объёмом кода на рекордах.
Не вижу иллюстрации.
S>Покажите, какой именно сценарий вы хотите написать на рекордах, и вам не удаётся из-за того, что это "очередное мутабельное говно".
Проблема не в том, удается что-то сделать или не удается. Проблема в том, что негрософт поощряет индусский стиль программирования. Чем плохо мутабельное состояние, вроде довольно известная вещь. И я не понимаю, зачем это делать там, где можно не делать. Тем более, что то же самое уже давно есть, только на два символа больше написать надо.
Здравствуйте, AlexRK, Вы писали:
ARK>Какая еще "чушь", "тактика", але. Негрософт сделал очередное мутабельное говно, впридачу к двум существующим. То, что оно иммутабельно по умолчанию — совершенно ничего не значит, такие "иммутабельные" классы и сейчас делать можно.
Ты о чем вообще? Оператор with не делает рекорды мутабельными.
Здравствуйте, AlexRK, Вы писали:
ARK>Не, ну необоснованно обвинять меня в какой-то там невнимательности — это тоже тактика так себе. В статье по ссылке вообще мутабельность никак не педалируется. Чтобы понять, что рекорды мутабельные, надо как раз наоборот быть внимательным.
ARK>Не вижу иллюстрации.
Ну, если вы так настаиваете, вот примерно как выглядит типичный иммутабельный класс на C# 8.0:
public sealed class Color: IEquatable<Color>
{
public byte R { get; }
public byte G { get; }
public byte B { get; }
public Color(byte r, byte g, byte b) => (R, G, B) = (r, g, b);
public void Deconstruct(out byte r, out byte g, out byte b) => (r, g, b) = (R, G, B);
public override int GetHashCode()
{
return R << 24 | G << 16 | B << 8;
}
public override bool Equals(object obj)
{
if (this == null)
return obj == null;
return obj is Color c && Equals(c);
}
public bool Equals([AllowNull] Color other)
{
if (this == null)
return other == null;
if (other == null)
return false;
return R == other.R && G == other.G && B == other.B;
}
public Color Clone() => new Color(R, G, B);
}
Вот как это же записывается на C# 9:
public sealed record Color(byte R, byte G, byte B);
Преимущества, имхо, очевидны. И это мы ещё не полезли в наследование — там код быстро становится ещё кучерявее. S>>Покажите, какой именно сценарий вы хотите написать на рекордах, и вам не удаётся из-за того, что это "очередное мутабельное говно". ARK>Проблема не в том, удается что-то сделать или не удается.
Именго к этому и сводятся все проблемы. ARK>Проблема в том, что негрософт поощряет индусский стиль программирования.
Стиль программирования бывает плохим не сам по себе, а потому что приносит измеримые проблемы. Любая "плохая" практика либо не является плохой, либо легко ткнуть в случай, где она приносит явное зло. ARK>Чем плохо мутабельное состояние, вроде довольно известная вещь. И я не понимаю, зачем это делать там, где можно не делать. Тем более, что то же самое уже давно есть, только на два символа больше написать надо.
Давайте конкретнее. Где вы хотите написать пару символов так, чтобы улучшить рекорды?
Покажите пример, где стреляет мутабельность рекордов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Преимущества, имхо, очевидны.
Если код состоит только из определений иммутабельных классов — то да.
ARK>>Проблема в том, что негрософт поощряет индусский стиль программирования. S>Стиль программирования бывает плохим не сам по себе, а потому что приносит измеримые проблемы. Любая "плохая" практика либо не является плохой, либо легко ткнуть в случай, где она приносит явное зло.
Как выглядит тычок в случай, например, нуллабельной ссылки?
Я по аналогии сделаю такую же ошибку с мутабельным состоянием.
ARK>>Чем плохо мутабельное состояние, вроде довольно известная вещь. И я не понимаю, зачем это делать там, где можно не делать. Тем более, что то же самое уже давно есть, только на два символа больше написать надо. S>Давайте конкретнее. Где вы хотите написать пару символов так, чтобы улучшить рекорды?
Я не хочу пару символов в рекордах, я бы предпочел их видеть иммутабельными (безусловно).
А то, что сейчас сделано — навесили бы атрибут для кодогенерации какой-нибудь.
S>Покажите пример, где стреляет мутабельность рекордов.
Там же, где любое изменяемое состояние. По этой причине его обычно минимизируют, не так ли?
Здравствуйте, AlexRK, Вы писали:
ARK>Проблема не в том, удается что-то сделать или не удается. Проблема в том, что негрософт поощряет индусский стиль программирования. Чем плохо мутабельное состояние, вроде довольно известная вещь. И я не понимаю, зачем это делать там, где можно не делать. Тем более, что то же самое уже давно есть, только на два символа больше написать надо.
То там кроме выделенного есть сравнение классов и рекордов
using System;
using System.Linq;
using static System.Console;
var user = "Lion-O";
var password = "jaga";
var rememberMe = true;
LoginResourceRecord lrr1 = new(user, password, rememberMe);
var lrr2 = new LoginResourceRecord(user, password, rememberMe);
var lrc1 = new LoginResourceClass(user, password, rememberMe);
var lrc2 = new LoginResourceClass(user, password, rememberMe);
WriteLine($"Test record equality -- lrr1 == lrr2 : {lrr1 == lrr2}");
WriteLine($"Test class equality -- lrc1 == lrc2 : {lrc1 == lrc2}");
WriteLine($"Print lrr1 hash code -- lrr1.GetHashCode(): {lrr1.GetHashCode()}");
WriteLine($"Print lrr2 hash code -- lrr2.GetHashCode(): {lrr2.GetHashCode()}");
WriteLine($"Print lrc1 hash code -- lrc1.GetHashCode(): {lrc1.GetHashCode()}");
WriteLine($"Print lrc2 hash code -- lrc2.GetHashCode(): {lrc2.GetHashCode()}");
WriteLine($"{nameof(LoginResourceRecord)} implements IEquatable<T>: {lrr1 is IEquatable<LoginResourceRecord>} ");
WriteLine($"{nameof(LoginResourceClass)} implements IEquatable<T>: {lrr1 is IEquatable<LoginResourceClass>}");
WriteLine($"Print {nameof(LoginResourceRecord)}.ToString -- lrr1.ToString(): {lrr1.ToString()}");
WriteLine($"Print {nameof(LoginResourceClass)}.ToString -- lrc1.ToString(): {lrc1.ToString()}");
public record LoginResourceRecord(string Username, string Password, bool RememberMe);
public class LoginResourceClass
{
public LoginResourceClass(string username, string password, bool rememberMe)
{
Username = username;
Password = password;
RememberMe = rememberMe;
}
public string Username { get; init; }
public string Password { get; init; }
public bool RememberMe { get; init; }
}
view rawProgram.cs hosted with ❤ by GitHub
Note: You will notice that the LoginResource types end in Record and Class. That pattern is not the indication of a new naming pattern. They are only named that way so that there can be a record and class variant of the same type in the sample. Please don’t name your types that way.
Здравствуйте, AlexRK, Вы писали:
ARK>Здравствуйте, Ночной Смотрящий, Вы писали:
НС>>Ты о чем вообще? Оператор with не делает рекорды мутабельными.
ARK>"set" тоже не делает?
with создает и возвращает новый инстанс рекорда, исходный он не меняет
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Serginio1, Вы писали:
S>>Про рекорды
IT>Что-то я не вижу, деконструктор они туда прикрутили? https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9
The compiler produces a Deconstruct method for positional records. The Deconstruct method has parameters that match the names of all public properties in the record type. The Deconstruct method can be used to deconstruct the record into its component properties:
public record Person(string FirstName, string LastName);
var person = new Person("Bill", "Wagner");
var (first, last) = person;
Console.WriteLine(first);
Console.WriteLine(last);
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, AlexRK, Вы писали:
ARK>Как выглядит тычок в случай, например, нуллабельной ссылки?
Примерно так:
public class Customer
{
public string Name {get;set};
private Manager Manager {get;set};
public override string ToString()=>$"Customer {Name} is managed by {Manager.Name}";
}
...
public static Customer CreateCustomer(string name, int managerId) => new Customer() {Name = name; Manager = db.Managers.GetById(managerId)}
... // где-то далеко-далеко, в совсем другом модуле:
Console.WriteLine(this.customer.ToString()); // BANG! We wish you a happy debugging
ARK>Я по аналогии сделаю такую же ошибку с мутабельным состоянием.
Это всё трёп, пока нет кода. ARK>Я не хочу пару символов в рекордах, я бы предпочел их видеть иммутабельными (безусловно).
Предпочтения — фигня. Интересна практическая ценность. ARK>А то, что сейчас сделано — навесили бы атрибут для кодогенерации какой-нибудь.
Ну, примерно так и сделано. S>>Покажите пример, где стреляет мутабельность рекордов. ARK>Там же, где любое изменяемое состояние. По этой причине его обычно минимизируют, не так ли?
Вот я как раз вижу минимизацию изменяемого состояния в рекордах. И в упор не вижу эту великую, непреодолимую проблему, которая вам так мозолит глаз.
Если вы неспособны проиллюстрировать своё мнение кодом, то вы ошиблись не только форумом, но и сайтом.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
ARK>>Я по аналогии сделаю такую же ошибку с мутабельным состоянием. S>Это всё трёп, пока нет кода.
Мне лень придумывать код, в комментариях по ссылке уже привели пример:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
MyRecord record = new MyRecord(5);
MyRecord clone = record with {};
// check that we do have a clone
Console.WriteLine(Equals(record, clone)); // true
Console.WriteLine(ReferenceEquals(record, clone)); // falsevar hash = new HashSet();
hash.Add(record);
Console.WriteLine(hash.Contains(record)); // true
Console.WriteLine(hash.Contains(clone)); // true
record.Danger = true; // uh oh
Console.WriteLine(hash.Contains(record)); // false
Console.WriteLine(hash.Contains(clone)); // false
}
}
public record MyRecord(int Value)
{
public bool Danger { get; set; }
}
namespace System.Runtime.CompilerServices
{
internal class IsExternalInit { }
}
Ога?
ARK>>Я не хочу пару символов в рекордах, я бы предпочел их видеть иммутабельными (безусловно). S>Предпочтения — фигня. Интересна практическая ценность. ARK>>А то, что сейчас сделано — навесили бы атрибут для кодогенерации какой-нибудь. S>Ну, примерно так и сделано.
Примерно так. Только местами через зад.
S>>>Покажите пример, где стреляет мутабельность рекордов. ARK>>Там же, где любое изменяемое состояние. По этой причине его обычно минимизируют, не так ли? S>Вот я как раз вижу минимизацию изменяемого состояния в рекордах. И в упор не вижу эту великую, непреодолимую проблему, которая вам так мозолит глаз.
Не понимаю, нахрена делать мутабельность? Вот что это кому дает?
Я не против рекордов, я сразу это сказал. Но ложку говна в бочку меда микрософт все же добавил.
S>Если вы неспособны проиллюстрировать своё мнение кодом, то вы ошиблись не только форумом, но и сайтом.
Здравствуйте, Serginio1, Вы писали:
ARK>>Не понимаю, нахрена делать мутабельность? Вот что это кому дает? S>Может кому то и нужно раз они оставили такую возможность.
Уже есть классы и структуры с такой возможностью. Много писать? Ну добавь атрибут для кодогенерации, если это прям так важно ( в жабе вся подобная кодогенерация выполняется через IDE, всем пофиг). Но нет, мы сделаем еще один раз то же самое, но с перламутровыми пуговицами.
S>Но вопрос а зачем эту мутабельность использовать?
Ну я не буду, а другой будет. Да и вообще, так можно много про что сказать.
Здравствуйте, AlexRK, Вы писали:
ARK>Здравствуйте, Serginio1, Вы писали:
ARK>>>Не понимаю, нахрена делать мутабельность? Вот что это кому дает? S>>Может кому то и нужно раз они оставили такую возможность.
ARK>Уже есть классы и структуры с такой возможностью. Много писать? Ну добавь атрибут для кодогенерации, если это прям так важно ( в жабе вся подобная кодогенерация выполняется через IDE, всем пофиг). Но нет, мы сделаем еще один раз то же самое, но с перламутровыми пуговицами.
Не понимаю твоего возмущения. Да есть лазейка, но если ты её будешь использовать то ССЗС S>>Но вопрос а зачем эту мутабельность использовать?
ARK>Ну я не буду, а другой будет. Да и вообще, так можно много про что сказать.
А вот кому то она возможно и будет нужна. И он будет плеваться из-за того, что такой возможности нет.
Думаю они много времени потратили, что бы такую возможность оставить. Аналоги рекордов есть в куче языков.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> А вот кому то она возможно и будет нужна.
Вот этого я и не могу понять. Если такая возможность нужна — почему просто не взять обычный класс? Для генерации всяких вспомогательных методов вводить в язык фичи необязательно.
Было бы четкое разделение — вот потенциально изменяемый класс, вот гарантированно неизменяемый рекорд.
S>И он будет плеваться из-за того, что такой возможности нет.
Почему тогда, скажем, анонимные классы мутабельными не сделали? Может кто-то плюется, что их нельзя поменять.
Здравствуйте, AlexRK, Вы писали:
НС>>Ты о чем вообще? Оператор with не делает рекорды мутабельными. ARK>"set" тоже не делает?
set ты должен явно прописать в своем рекорде, сделать это намеренно. Ровно так же намеренно ты можешь использовать обычный класс, тоже мутабельный. Непонятно в чем тут криминал, и что бы дал абсолютный запрет на мутабельность рекордов.