C#向下推广泛型

时间:2015-03-15 17:29:29

标签: c# .net wpf generics casting

在我们的项目中,我们使用.net WPF与MEF和棱镜。 我必须做一些任务,作为其中的一部分,我有不同的Model类,都实现了IModel接口(让我们称之为Model1,Model2,Model3)。 对于每个模型类,我需要创建一个视图模型(ViewModel1,ViewModel2,ViewModel3)。 我想以一些通用的方式做到这一点,因此它是可扩展的,如果明天有人将在我不知道的不同dll中实现IModel,我仍然可以为它创建一个视图模型。

我虽然喜欢这样的事情:

    [InheritedExport]
public interface IViewModelFactory<T>
{
    IViewModel Create(string id, IEnumerable<IModel> modelsList);
}

public class ViewModelFactory : IViewModelFactory<Model1>
{
    public IViewModel Create(string id, IEnumerable<IModel> modelsList)
    {
        return new ViewModel1(targetId, modelsList);;
    }
}

public class FactoryLocator
{
    public static IViewModelFactory<T> GetFactory<T>(T parameters)
    {
        return ServiceLocator.Current.GetInstance<IViewModelFactory<T>>();
    }
}

然后我将以这种方式使用它:

        public void CreateAndAddVM(IList<IModel> modelsList)
    {
        var factory = FactoryLocator.GetFactory(modelsList.FirstOrDefault());
        var vm = factory.Create(_id, modelsList);
        ViewModels.Add(vm);
    }

当我到达FactoryLocator时,类型实际上是IModel接口而不是Model1 / 2/3。

有什么方法可以让它以某种方式运作?或者可能是实现此要求的另一种方式?

2 个答案:

答案 0 :(得分:0)

你应该从像这样定义的界面开始

public interface IViewModelFactory<T> where T : IModel 
{
    IViewModel Create(string id, IEnumerable<T> modelsList);
}

它实际上会强制在未来的实施者身上进行正确的输入。

答案 1 :(得分:0)

正如我在评论中提到的那样。此时,任何人都可以使用可能不适合它的模型创建视图模型。

例如,如果您的ViewModel依赖于Model1,那么没有什么可以阻止我向您工厂中的Create方法提供Model2列表。

请考虑以下事项:

public abstract class ViewModelBase<TModel> where TModel : IModel

上面的示例将允许您的ViewModel指定它代表的模型,但是假设ViewModel只有一个Model,而情况可能并非总是如此。

在这种情况下,您的ViewModelBase类应具有ID和TModel的Model属性。

确保 IModel 继承自 INotifyPropertyChanged这将允许 TModel 成为 ObservableCollection