2016-08-24 2 views
1

Я пытаюсь разобраться в Generics и рефакторинг существующего класса. Я был бы признателен за отзывы о том, можно ли это сделать лучше.C# Generics - это можно сделать лучше?

У меня есть несколько ViewModels, которые реализуют подобное поведение и могут быть получены из общего класса. Примером может служить:

public class SelectSupplierViewModel : SelectViewModel<SupplierAModel> 

ПоставщикAModel - это модель ISelectModel.

Следующий класс включает вид, который отображает меню элементов для работы с несколькими типами данных

public class SelectViewModel<T> : ViewModelBase where T : ISelectModel 
{ 
    public Action<SelectViewModel<T>> OnItemSelected; 

    public IEnumerable<T> Selections { get; set; } 

    public T SelectedItem 
    { 
     get { return null; } 
     set { 
      RaisePropertyChanged(); 
      OnItemSelected?.Invoke(this); 
     } 
    } 

    . 
    . 
    . 

OnItemSelected подключен к обработчику в отдельном классе. Он выполняется на ранее «Invoke»:

private void OnSupplierSelected(SelectViewModel<SelectAModel> viewModel) 
{ 
    // When I inspect viewModel I can see that viewModel is a 
    // SelectSupplierViewModel, and I need to access properties on 
    // this. 

    // Is it possible to do so without casting viewModel to  
    // SelectSupplierViewModel? 
} 

Это не было возможности иметь метод принимающую в SelectSupplierViewModel как класс SelectViewModel ожидает SelectViewModel.

Thankyou!

+0

Если 'OnSupplierSelected()' требует 'SelectSupplierViewModel', то сделайте параметр более производным. В противном случае вы нарушаете https://en.wikipedia.org/wiki/Liskov_substitution_principle – itsme86

+0

Я хотел бы принять параметр SelectSupplierViewModel, но я не могу понять, как это сделать, поскольку действие менее конкретное. – IntoTheBlue

+0

Это относится к обзору кода. Здесь нет ошибки или проблемы. Вы получите гораздо лучшую обратную связь на сайте, предназначенную именно для просмотра кода. – InBetween

ответ

2

Вы можете добавить тип, происходящий в параметры типа SelectViewModel<> так:

public class SelectViewModel<TModel, TViewModel> : ViewModelBase 
    where TModel : ISelectModel, TViewModel: SelectViewModel<TModel, TViewModel> 
{ 

Обратите внимание, что вы должны добавить общий тип ограничения для TViewModel, так что вы можете бросить this к TViewModel при вызове обработчика события ,

Используйте TViewModel для декларации событий:

public Action<TViewModel> OnItemSelected; 

... и для его вызова:

OnItemSelected?.Invoke((TViewModel)this); 

Выведение из нового базового класса похож - просто добавить тип вы собираетесь объявить список параметров типа:

public class SelectSupplierViewModel 
    : SelectViewModel<SupplierAModel, SelectSupplierViewModel> 
{ 

Вот пример: https://dotnetfiddle.net/8gHBwj

+0

Это имеет смысл, спасибо. Я попробую. – IntoTheBlue

Смежные вопросы