使用模式匹配,我如何从T基础调用方法

时间:2018-03-22 20:44:25

标签: c# generics pattern-matching

我创建了一个viewmodel基础,其中每个viewmodel都有一个集合和一个重新加载集合的方法。

public interface ILegalViewModelBase<T>
{
    ObservableCollection<T> MasterCollection { get; set; }
    void ReloadCollection();
}

public abstract class LegalViewModelBase<T> : BindableBase, ILegalViewModelBase<T>
{
    public ObservableCollection<T> MasterCollection
    {
        get => _masterCollection;
        set => SetProperty(ref _masterCollection, value, ReloadCollection);
    }
    private ObservableCollection<T> _masterCollection;

    public abstract void ReloadCollection();
}

在Codebehind中,我试图确定DataContext是否为ILegalViewModelBase类型,如果是,请调用ReloadCollection()方法。 (我知道这个&#39;打破了mvvm。)

我可以使用以下代码检查T是否为<{1}}

if (DataContext.GetType().GetGenericTypeDefinition() == typeof(ILegalViewModelBase<>) /* typeof(ILegalViewModelBase<>) */)
{
    ....
}

但是我无法弄清楚如何将其转换为可用的对象。我以前使用下面的代码完成了非泛型类。

if (DataContext is AttorneyClaimsViewModel vm)
{
    vm.ReloadCollection();
}

我如何对泛型做同样的事情?

1 个答案:

答案 0 :(得分:4)

你不能使用泛型来做到这一点。原因是你可能不知道那时T是什么:

if (DataContext is LegalViewModelBase<> vm)
{
    var col = vm.MasterCollection; // What type is col??
}

在您的特定情况下,您对集合不感兴趣,而是对类型参数无关的方法感兴趣。在这种情况下,将其移动到不同的非通用接口,您将能够使用模式匹配:

public interface ILegalViewModelBase 
{
    void ReloadCollection();
}

public interface ILegalViewModelBase<T> : ILegalViewModelBase
{
    ObservableCollection<T> MasterCollection { get; set; }
}

public abstract class LegalViewModelBase<T> : BindableBase, ILegalViewModelBase<T>
{
    public ObservableCollection<T> MasterCollection
    {
        get => _masterCollection;
        set => SetProperty(ref _masterCollection, value, ReloadCollection);
    }
    private ObservableCollection<T> _masterCollection;
}

现在您可以使用基接口进行模式匹配:

if (DataContext is ILegalViewModelBase vm)
{
    vm.ReloadCollection();
}