위처럼 base class 생성자에서 override 가능한 가상함수 호출하면 문제가 발생할 수 있다.
따라서, 만약의 경우를 대비하여 생성자에서 가상함수를 부르지 않도록 하자.
WPF에서 제공하는 dependency property는 metadata의 콜백함수를 override할 수 있는 기능을 제공한다.
dependecny property SetValue를 호출하면 해당 콜백함수가 호출된다.
예를들어,
public class Aquarium : DependencyObject
{
...
public Aquarium()
{
Debug.WriteLine("Base class parameterless constructor running.");
// Set typical aquarium temperature.
TempCelcius = 20;
Debug.WriteLine($"Aquarium temperature (C): {TempCelcius}");
}
...
}
위 base class는 TempCelciusProperty dependency property를 등록했고, 생성자에서 SetValue를 호출한다.
public class TropicalAquarium : Aquarium
{
...
static TropicalAquarium()
{
Debug.WriteLine("Derived class static constructor running.");
// Create a new metadata instance with callbacks specified.
PropertyMetadata newPropertyMetadata = new(
defaultValue: 0,
propertyChangedCallback: new PropertyChangedCallback(PropertyChangedCallback),
coerceValueCallback: new CoerceValueCallback(CoerceValueCallback));
// Call OverrideMetadata on the dependency property identifier.
TempCelciusProperty.OverrideMetadata(
forType: typeof(TropicalAquarium),
typeMetadata: newPropertyMetadata);
}
// Parameterless constructor.
public TropicalAquarium()
{
Debug.WriteLine("Derived class parameterless constructor running.");
s_temperatureLog = new List<int>();
}
// Property-changed callback.
private static void PropertyChangedCallback(DependencyObject depObj,
DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("Derived class PropertyChangedCallback running.");
try
{
s_temperatureLog.Add((int)e.NewValue);
}
catch (NullReferenceException)
{
Debug.WriteLine("Derived class PropertyChangedCallback: null reference exception.");
}
}
...
}
위 derive class는 static 생성자에서 PropertyChangedCallback, CoerceValueCallback을 override한다.
만약, 위 derived class를 생성할 경우, base class 생성자가 먼저 호출 될 것이고, SetValue를 호출하여, 아직 초기화하지 않은 s_temperatureLog를 참조하여 에러가 발생한다.
ms에서는 다음과 같은 방법으로 해당 문제를 피하라고 제안한다.
[WPF] Command (0) | 2022.04.20 |
---|---|
[WPF] Dependency Property Metadata (0) | 2022.04.19 |
[WPF] Databinding (0) | 2022.04.18 |
[WPF] Pack uri (0) | 2022.04.15 |
c# (WPF) Data Binding 에 대해서 (0) | 2021.05.31 |
댓글 영역