컴파일 타임 동안 할당이 금지되는 경우 생성자 지정 및 개인 설정자에 충실해야합니다. 이 많은 단점이있다 그러나 - 당신은 내가 이런 식으로 뭔가를 제안 등
새 멤버 초기화,도 XML을 deseralization 등을 사용할 수 없습니다 : 여기
public class IssuerRecord
{
public string PropA { get; set; }
public IList<IssuerRecord> Subrecords { get; set; }
}
public class ImmutableIssuerRecord
{
public ImmutableIssuerRecord(IssuerRecord record)
{
PropA = record.PropA;
Subrecords = record.Subrecords.Select(r => new ImmutableIssuerRecord(r));
}
public string PropA { get; private set; }
// lacks Count and this[int] but it's IReadOnlyList<T> is coming in 4.5.
public IEnumerable<ImmutableIssuerRecord> Subrecords { get; private set; }
// you may want to get a mutable copy again at some point.
public IssuerRecord GetMutableCopy()
{
var copy = new IssuerRecord
{
PropA = PropA,
Subrecords = new List<IssuerRecord>(Subrecords.Select(r => r.GetMutableCopy()))
};
return copy;
}
}
IssuerRecord 훨씬 더 설명하고 유용하다. 다른 곳으로 전달하면 쉽게 변경할 수없는 버전을 만들 수 있습니다. 불변에 대해 작동하는 코드는 읽기 전용 논리를 가져야하므로 IssuerRecord와 동일한 유형인지는 중요하지 않습니다. 개체를 래핑하는 대신 각 필드의 복사본을 만듭니다. 개체가 다른 곳에서 변경 될 수 있기 때문입니다. 그러나 특히 순차적 인 동기화 호출에는 필요하지 않을 수 있습니다. 그러나 어떤 불변 복제본을 "나중에"컬렉션에 저장하는 것이 더 안전합니다. 일부 코드에서 수정을 금지하지만 객체 상태에 대한 업데이트를받을 수있는 기능이 필요한 경우 응용 프로그램에서 래퍼가 될 수 있습니다.
var record = new IssuerRecord { PropA = "aa" };
if(!Verify(new ImmutableIssuerRecord(record))) return false;
당신이 C++ 측면에서, 당신은 "IssuerRecord의 CONST"로 ImmutableIssuerRecords을 볼 수 있다고 생각합니다. 모든 자식 (Subrecords 예제)에 대한 복사본을 만들 것을 제안하는 이유는 불변 객체가 소유하고있는 객체를 보호하기 위해 여분의 조치를 취해야한다는 것입니다.
ImmutableIssuerRecord.Subrecors는 여기에서 IEnumerable이고 Count 및 this []가 부족하지만 IReadOnlyList가 4.5 버전으로 제공되며 원하는 경우 docs에서 복사하여 나중에 쉽게 마이그레이션 할 수 있습니다.
등은 Freezable로,뿐만 아니라 다른 방법이 있습니다 :
다시 코드가 덜 읽을 수있게하고, 컴파일시 보호를 제공하지 않습니다
public class IssuerRecord
{
private bool isFrozen = false;
private string propA;
public string PropA
{
get { return propA; }
set
{
if(isFrozen) throw new NotSupportedOperationException();
propA = value;
}
}
public void Freeze() { isFrozen = true; }
}
. 그러나 객체가 정상적으로 생성 된 다음 준비가 끝나면 고정 할 수 있습니다.
작성자 패턴 또한 고려해야 할 사항이지만 내 관점에서 너무 많은 "서비스"코드를 추가합니다.
클래스 외부에서 값을 설정해야하거나 클래스 자체에서 값을 설정할 수 있습니까? 클래스가 그것을 할 수 있다면, 매개 변수없는 생성자를 가질 수 있습니다. –
참조 : http://stackoverflow.com/questions/355172/how-to-design-an-immutable-object-with-complex-initialization?rq=1 – aquinas
어떻게 이러한 속성을 초기화 하시겠습니까? –