C# 8에 추가된 기본 인터페이스 메서드는 인터페이스 정의가 업데이트 됨에 따라 하위 호환을 유지하면서 기능을 확장할 수 있도록 해줍니다.
C# 8이 나올 때 기능적으로는 대략 알고는 있었지만 딱히 활용할 곳이 없어서 잊고 있다가 오늘 이렇게 활용할 수 있겠구나 싶어서 간단히 테스트 코드를 구현해보았습니다.
컨셉은, View의 object 타입의 DataContext를 기본 인터페이스 메서드
를 이용해 ViewModel로 캐스팅 된 것을 바로 쓰자는 것이였는데, 결과적으로는 실패했습니다. 한번 코드를 보시죠.
var view = new SomethingView();
// view.ViewModel = new SomethingViewModel(); // ViewModel에 접근이 안됨
interface IHaveViewModel<T>
where T : class
{
object? DataContext { get; set; }
public T? ViewModel { get => DataContext as T; set => DataContext = value; }
}
abstract class View
{
public object? DataContext { get; set; }
}
class SomethingView : View, IHaveViewModel<SomethingViewModel>
{
}
class SomethingViewModel
{
public int Value { get; set; }
}
안타깝게도? 인터페이스에서 구현된 ViewModel은 해당 인터페이스로만 접근이 되도록 제한이 되어 있습니다. 그래서 ViewModel을 호출할 수 없는데요, 이것을 굳이 캐스팅 해서 쓰자 하자면, 배보다 배꼽이 더 커집니다.
(view as IHaveViewModel<SomethingViewModel>).ViewModel = new SomethingViewModel(); // 오! 이건 아닌것 같아요
어짜피 기본 인터페이스 메서드
의 기능은 인터페이스
관점에서의 유익함이기 때문에 인터페이스로만 접근되도록 한 것은 올바른 선택이긴 한 것 같습니다만… 이거 어디다가 써먹을 수 있을까요?
결국엔 중간 View 계층을 둬서 ViewModel 인스턴스에 접근이 되도록 하는게 제가 필요한 기능을 구현하는 목적에는 부합됩니다.
var view = new SomethingView();
view.ViewModel = new SomethingViewModel(); // 이렇게;;
abstract class View
{
public object? DataContext { get; set; }
}
abstract class ExtandView<T> : View
where T : class
{
public T? ViewModel { get => DataContext as T; set => DataContext = value; }
}
class SomethingView : ExtandView<SomethingViewModel>
{
}
class SomethingViewModel
{
public int Value { get; set; }
}
관련해서 좋은 아이디어나 생각 댓글로 공유 부탁해요~