WPF 핵심 베이스 클래스 (1) - DispatcherObject, DependencyObject

8323 단어 CwpfC

WPF의 핵심 베이스 클래스 중 DispatcherObject와 DependencyObject에 대해서 알아보자.

닷넷 프레임워크는 코드가 https://referencesource.microsoft.com 사이트에 공개되어 있다. 참고용으로 클래스마다 제목에 레퍼런스 소스 링크를 걸어두었다.

클래스 별로 public으로 공개된 인터페이스(함수, 프로펄티)만 간략하게 코드로 넣었다.

DispatcherObject

자신이 생성된 쓰레드에서 접근되어야 하는 객체이고 따라서 상속받는 객체들은 Thread Safe이 보장되지 않는다

public abstract class DispatcherObject {
	public Dispatcher Dispatcher { get; }
    public bool CheckAccess();
    public void VerifyAccess();
}

CheckAccess, VerifyAccess, Dispatcher(getter)는 free-threaded하게 접근이 가능하다.

bool CheckAccess()의 경우 자신이 생성된 쓰레드에서 접근되었는지 여부를 반환한다. 내부적으로는 Dispatcher.Thread와 Thread.CurrentThread가 같은지 검사한다.

void VerifyAccess()는 자신이 생성된 쓰레드에서 접근되지 않았을 경우 예외를 발생시킨다. (InvalidOperationException)

DependencyObject

DependencyProperty를 지원하기 위한 베이스 클래스

public abstract class DependencyObject : DispatcherObject
{
	DependencyObjectType DependencyObjectType { get; }
	bool IsSealed { get; }
	void ClearValue(DependencyProperty dp);
	void ClearValue(DependencyPropertyKey key);
	void CoerceValue(DependencyProperty dp);
	LocalValueEnumerator GetLocalValueEnumerator();
	object GetValue(DependencyProperty dp);
	void InvalidateProperty(DependencyProperty dp);
	object ReadLocalValue(DependencyProperty dp);
	void SetCurrentValue(DependencyProperty dp, object value);
	void SetValue(DependencyProperty dp, object value);
	void SetValue(DependencyPropertyKey key, object value);
}

DependencyProperty를 위한 다양한 인터페이스를 제공하고 있다.

DependencyObjectType는 DependencyObject를 상속받는 타입에 대한 식별자로 내부적으로 캐싱된다. DependencyObjectType 프로펄티는 런타임에 현재 타입에 대한 식별자를 반환한다.

bool IsSealed는 object가 Read-Only 상태인지를 나타낸다.

나머지는 DependencyProperty를 배우면서 알아보도록 하자.

추가

레퍼런스 소스를 보다가 눈에 띄는 부분이 있었는데 DependencyObject에서 파생클래스의 Equals와 GetHashCode의 오버라이드를 막고 있다.

// DependencyObject.cs
public override sealed bool Equals(Object obj)
{
	return base.Equals(obj);
}

public override sealed int GetHashCode()
{
	return base.GetHashCode();
}

DependencyObject.cs 주석에 따르면 Equals 오버라이드가 합리적인 경우를 2가지로 보고 있다.

  1. 값 타입인 경우(pass by copy)
  2. 불변 객체인 경우

DependencyObject는 레퍼런스 타입이므로 1번은 패스
DependencyObject를 상속받는 객체는 DependencyProperty를 가지고 있기 때문에 DependencyObject가 불변객체가 될 수 없다.
따라서 Equals와 GetHashCode의 오버라이드를 막고 있다.

좋은 웹페이지 즐겨찾기