jrchs
6월 10, 2024, 12:12오전
1
internal class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine(a.GetCount());
a.SetByte();
var b0 = a.GetByte(0);
var b1 = a.GetByte(1);
Console.WriteLine(b0 is null);
Console.WriteLine(b1 is null);
Console.Read();
}
}
public class A
{
protected virtual List<byte[]?> LM => new() { null, null, };
public int GetCount()
=> LM.Count;
public void SetByte()
{
LM[0] = new byte[2] { 0x01, 0x02, };
LM[1] = new byte[2] { 0x03, 0x04, };
}
public byte[]? GetByte(int idx)
=> LM[idx];
}
이 코드에서 b0와 b1이 항상 null이 됩니다.
LM은 상속 받는 클래스마다 초기값이 달라져야 하고 (그래서 virtual property로 만들었습니다.), 런타임에도 값을 변경해야 합니다. 어떻게 코드를 변경해야 할까요?
태현짱와우
6월 10, 2024, 12:17오전
2
LM {get; set;} = new() { null, null, }; 로 바꾸면 될 거 같아요 LM => new() { null, null, };은 getter만 정의한거라 LM을 호출할 때마다 new() {null, null,}을 반환하겟다는거랑 같은 말입니다. 즉 setter가 없는 LM { get { return new() { null, null, }; } } 와 같은거죠.
2개의 좋아요
jrchs
6월 10, 2024, 12:20오전
3
감사합니다.
setter가 객체 자체를 변경하는게 아니라 객체의 item을 변경할 때도 있어야 하나보네요.
scurd
6월 10, 2024, 12:22오전
4
protected List<byte ?> _list = new List<byte ?> { null, null };
protected virtual List<byte ?> LM => _list;
*phind님 충성충성.
code
6월 10, 2024, 7:01오전
5
@태현짱와우 님 말씀처럼 property 잘못써서 생긴 결과고
약간 java 코드 같아서 cs 코드로 바꿔 봤습니다.
internal class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine(a.Count);
//a[0] = [0x01, 0x02];
//a[1] = [0x03, 0x04];
// or
// a.Init();
Console.WriteLine(a[0] is null);
Console.WriteLine(a[1] is null);
Console.Read();
}
}
public class A
{
public A()
{
LM[0] = [0x01, 0x02];
LM[1] = [0x03, 0x04];
}
public void Init()
{
LM[0] = [0x01, 0x02];
LM[1] = [0x03, 0x04];
}
protected virtual List<byte[]?> LM { get; } = [null, null];
public int Count => LM.Count;
public byte[]? this[int i]
{
get => LM[i];
set => LM[i] = value;
}
}
jrchs
6월 10, 2024, 7:14오전
6
객체를 변경하는게 아니라 초기에 생성한 객체의 item을 변경하는건데 setter가 필요한가요?
접근자인 "속성"을 생성자로 사용하고 있기에 발생한 혼란입니다.
문법적으로 아무런 문제가 없어도, 그 의미가 생성자인 경우 아래와 같이 메서드로 정의하는 것이 질문과 같은 혼란을 막을 수 있습니다.
protected virtual List<byte[]?> NewList() => new() { null, null, };
닷넷의 많은 라이브러리는 이러한 패턴을 따르고 있습니다. 예를 들면,
var id = Guid.NewGuid();
질문의 속성을 메서드로 변경하면, 클래스 A 코드의 이상함이 쉽게 드러납니다.
public class A
{
protected virtual List<byte[]?> NewList() =>
[null, null,];
public int GetCount() =>
NewList().Count;
public void SetByte()
{
NewList()[0] = [0x01, 0x02,];
NewList()[1] = [0x03, 0x04,];
}
public byte[]? GetByte(int idx) =>
NewList()[idx];
}
물론, 이 코드는 @jrchs 님이 의도한 코드는 아닐 것입니다.
아마도 문맥이 완전히 다른 초기화와 설정을 같은 것으로 취급하고 있는 듯합니다.
setter 가 없어도, 초기화는 가능합니다.
2개의 좋아요