如何通过模式匹配调用泛型T基类中的ReloadCollection方法?
如何通过模式匹配调用泛型基类中的ReloadCollection方法?
嘿,我来帮你搞定这个问题!你已经定义了一个泛型ViewModel基类和对应的接口,现在想通过模式匹配来调用其中的ReloadCollection方法对吧?这里有几种实用的方案,一步步来看:
首先先把你提供的基类代码补全(方便后续示例参考):
using System.Collections.ObjectModel; using Prism.Mvvm; // 假设使用Prism的BindableBase,替换成你实际用的MVVM框架基类即可 public interface ILegalViewModelBase<T> { ObservableCollection<T> MasterCollection { get; set; } void ReloadCollection(); } public abstract class LegalViewModelBase<T> : BindableBase, ILegalViewModelBase<T> { private ObservableCollection<T> _masterCollection = new(); public ObservableCollection<T> MasterCollection { get => _masterCollection; set => SetProperty(ref _masterCollection, value, ReloadCollection); } public abstract void ReloadCollection(); // 抽象方法,由子类实现具体逻辑 }
方案1:用is关键字做类型模式匹配
如果你有一个未知类型的ViewModel实例,想要判断它是否属于ILegalViewModelBase<T>的实现类,然后调用方法,最直接的方式就是用is模式匹配:
场景A:知道具体的泛型参数T
比如你明确这个ViewModel是针对Customer类型的:
object viewModel = GetYourViewModelInstance(); if (viewModel is ILegalViewModelBase<Customer> customerVm) { customerVm.ReloadCollection(); }
场景B:匹配任意泛型参数的实现(C# 10+)
如果你不需要关心具体的T类型,只想调用ReloadCollection,可以用C# 10引入的泛型通配符模式,用*匹配任意泛型参数:
object viewModel = GetYourViewModelInstance(); if (viewModel is ILegalViewModelBase<*> anyLegalVm) { anyLegalVm.ReloadCollection(); }
方案2:在switch语句/表达式中批量处理
如果需要同时处理多种不同类型的ViewModel,switch结构会让代码更清晰:
传统switch语句
object viewModel = GetYourViewModelInstance(); switch (viewModel) { case ILegalViewModelBase<Customer> customerVm: customerVm.ReloadCollection(); break; case ILegalViewModelBase<Order> orderVm: orderVm.ReloadCollection(); break; // 匹配任意泛型参数的情况 case ILegalViewModelBase<*> anyLegalVm: anyLegalVm.ReloadCollection(); break; default: // 处理非LegalViewModelBase类型的逻辑 break; }
简洁的switch表达式
如果只是执行简单操作,switch表达式会更紧凑:
object viewModel = GetYourViewModelInstance(); var isReloaded = viewModel switch { ILegalViewModelBase<Customer> c => { c.ReloadCollection(); return true; }, ILegalViewModelBase<Order> o => { o.ReloadCollection(); return true; }, ILegalViewModelBase<*> a => { a.ReloadCollection(); return true; }, _ => false };
方案3:结合as运算符的简洁写法
如果你只需要调用方法,不需要额外的条件判断,用as配合空传播运算符会非常简洁:
object viewModel = GetYourViewModelInstance(); // 匹配任意泛型参数的实现,转换后调用方法(转换失败时不会报错) (viewModel as ILegalViewModelBase<object>)?.ReloadCollection();
注意事项
- 泛型通配符模式(
*)需要C# 10及以上版本支持,如果你用的是更早的C#版本,只能指定具体的泛型参数,或者通过反射处理(但反射比较繁琐,优先升级版本或指定具体类型)。 - 调用
ReloadCollection方法本身不需要知道具体的泛型参数T,因为这个方法是无参数的,所以大部分场景下用通配符或者object作为泛型参数就能满足需求。
内容的提问来源于stack exchange,提问作者highboi
相关产品推荐
相关产品推荐

