원래 클래스를 구현할 때 GetHashCode나 Equals 메서드 같은 것을 구현하는게 나중에 HashTable이나 Dictionary 등에 데이터 타입을 결합해서 사용하는 경우를 고려해서 꼭 필요하긴 하지만 손이 많이 가는 작업인데, record를 쓰면 이 부분이 많이 줄어드는 효과가 있는 것으로 기억합니다.
클래스 생성자는 그래서 클래스이든 레코드이든 어디서나 쓸 수 있는게 맞고, 클래스 생성자를 안쓴다고 하면 아래처럼 속성으로만 남기되 immutable 속성으로 남기는 것도 가능한 것으로 알고 있습니다.
class UserInfo() {
public string name { get; init; }
public string sex { get; init; }
}
다만 with 오퍼레이터는 record 타입인 경우에만 쓸 수 있게 되어있네요!
var a = new UserInfo() { name = "a", sex = "male", };
// UserInfo 타입이 레코드 타입이 아니라서 아래 코드는 컴파일 실패가 발생합니다.
var b = a with { name = "b", sex = "female", };
추후 서로간의 상속이 불가하고 record에 자동구현된 부분들이 동작에 의도치않은 차이를 발생시키기 때문에 class의 역할을 record가 아무생각없이 대체하기엔 꽤나 숙고가 필요합니다.
객체의 용도가 record에 너무 적합하고 코드가 드라마틱하게 감량되는게 아니라면 일단 class인게 맞다고 생각합니다.
member가 아니라 parameter라는 관점에서, 제가봐온 C#은 인자의 불변성을 보장 해준적이 없습니다.
인자 하나로 불변 프로퍼티 만들고 이것저것 알아서 다하는 record가 별종으로 새로튀어나온것인데, 원래있던 class에서 그러한 모든게 어떠한 명시 없이 자동구현되어선 안된다고 생각합니다.
자동 readonly처리는 미래에 기본생성자와 함수의 인자를 포괄하는 새로운 문법이 발명될때로 미뤄져야합니다. 머 하다못해 attribute라도 나오겠죠
// 1. primary contructor
public class Test(string name)
{
}
// 2. 그냥 클래스.
public class Test
{
private string _name;
public Test(name)
{
_name = name;
}
}
이게 달라지면 더 문제일 거라는 생각이 듭니다.
1번일 때 readonly 가 적용되지 않아 문제라고 인식한다면
2번일 때에도 문제라고 얘기햬야하는데, 그렇지는 않으니까요.
게다가 readonly 가 필요하다면
public class Test(string name)
{
private readonly string _name = name;
}
이 방법이 있으니까요.
primary constructor 가 강제 사항이 아니기 때문에 @BigSquare 님의 말씀처럼 원래 class 의 성격이 유지되어야 한다고 봐욤 ㅇㅅㅇ/
이견으로는 생성자에서 초기화 되는 동일 값(별도의 인스턴스 생성 없는)의 경우 개발환경에서 필드 값을 readonly로 추천 하고 기본 값을 readonly로 해도 그 반대를 필드 선언할 수 있기 때문에 문제가 없다는 입장이지만 class가 전통적으로 무엇이 되었든 기본값이 readonly가 아니기 때문에 납득이 됩니다.
다만 기본 생성자로 전달된 값은 변경이 되면서 클래스 안에서 전역적으로 접근된다는 점은 신경쓰이네요. 그것을 막는 유일한 방법은 ‘readonly int value = value;’ 방법밖에는 없습니다.