c#泛型——可以做得更好吗?

本文关键字:更好 泛型 | 更新日期: 2023-09-27 18:03:52

我试图得到我的头围绕泛型和重构一个现有的类。我希望能得到反馈,知道是否可以做得更好。

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

public class SelectSupplierViewModel : SelectViewModel<SupplierAModel>

suppliermodel是一个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。

谢谢!

c#泛型——可以做得更好吗?

您可以在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