C#泛型 - 可以做得更好吗?

时间:2016-08-24 16:04:03

标签: c# generics

我试图了解Generics并重构现有的课程。我希望得到关于是否可以做得更好的反馈。

我有许多ViewModel实现类似的行为,可以从一个公共类派生。一个例子是:

public class SelectSupplierViewModel : SelectViewModel<SupplierAModel>

SupplierAModel是一个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?
}

由于SelectViewModel类需要SelectViewModel,因此不可能有一个接受SelectSupplierViewModel的方法。

三江源!

1 个答案:

答案 0 :(得分: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