나는 대부분 Vlad의 제안에 따라이 약간에 흥분. 밝혀졌습니다 은이를 추상화하기 위해 단일 제네릭 클래스를 사용합니다. 결과는 다음과 같습니다.
public class Overridable<T>
{
private Func<T> _calculate;
private readonly Func<T, T, bool> _compare;
protected T _t;
public Overridable(Func<T> calculate, Func<T, T, bool> compare)
{
_calculate = calculate;
_compare = compare;
}
public T Value
{
get { return _compare(_t, default(T)) ? _calculate() : _t; }
set { _t = _compare(value, _calculate()) ? default(T) : value; }
}
}
유형을 하위 클래스에서 설정할 때까지 알 수 없으므로 비교 위임을 전달해야합니다. 그래서 간단한 ==
은 그것을 자르지 않을 것입니다. 쉬운 경로를 가서 Func 대리자를 사용했지만 어떤 이유로 든 .NET 2.0에 맞게 조정해야한다면 일반 대리자로 바꿀 수 있습니다.
null
대신 default(T)
을 사용하고 있습니다. 이것은 Nullable<T>
의 기본값이 null
(또는보다 정확하게는 정의되지 않았지만 동일하게 작동 함)이기 때문에 작동합니다.
nullable 형식에 대해 Overridable<T>
을 선언하지 못하게하지 않습니다. 당신이 바람을 피우는 것은 런타임 오류가 아니지만 유용하지는 않습니다. Overridable<decimal>.Value
을 null
으로 설정하면 컴파일러 오류가 발생합니다. default(decimal)
으로 설정하면 값 계산으로 되돌아갑니다.
이 경로는 내가 사용하고있는 클래스의 속성이 결국 XML로 전송 된 직렬화 가능 객체를 채워야하기 때문에 진행되었습니다. xml의 스키마에는 정수, 소수 및 문자열의 혼합으로 정의 된 숫자 필드가 포함됩니다.
당신은 지금처럼 Overriddable 클래스를 사용
private Overridable<decimal?> _excessWages =
new Overridable<decimal?>(CalculateExcessWages, (x,y) => x == y);
public virtual decimal? ExcessWages
{
get
{
return _excessWages.Value;
}
set
{
_excessWages.Value = value;
}
}
내가이과에 달렸다 유일한 문제는이 필드 이니셜 라이저에서 사용할 수 없습니다 수 CalculateExcessWages
가 비 정적 방법이었다. 내 클래스의 모든 속성이 정적이 아니기 때문에 생성자의 모든 뒷받침 필드를 초기화해야했습니다.
실제로 무엇을 요구하고 있습니까? 속성이'virtual'으로 선언되었지만 텍스트에서 setter 내부의 코드 구조에 대해 더 많이 묻습니다. –
죄송합니다. 나는 가상을 제거했다. 내가 관심있는 것이 아닙니다. 최종 사용자의 관점에서 '우선 할 수있는'것에 관심이 있습니다. –