2014-11-17 283 views
0

我有以下代码:泛型类型的泛型?

public abstract class ListPresenter<TView, TModel, TEntity> : Presenter<TView, TModel> 
    where TView : IListView<TModel> 
    where TModel : EntityListViewModel<TEntity> 
    where TEntity : class, IEntity 
{ 
    public ListPresenter(TView view, TModel model) 
     : base(view, model) 
    { 
    } 
} 

有什么办法,以避免第三个参数?如果我尝试使用:

public abstract class ListPresenter<TView, TModel> : Presenter<TView, TModel> 
    where TView : IListView<TModel> 
    where TModel : EntityListViewModel<IEntity> 

我得到:

错误3型“PuntoVenta.ViewModels.SaleListViewModel”不能在泛型类型或方法“PuntoVenta.Presentation被用作类型参数“的TModel” .ListPresenter”。没有从'PuntoVenta.ViewModels.SaleListViewModel'到'PuntoVenta.ViewModels.EntityListViewModel'的隐式引用转换。 C:\ Users \ Marc \ Dropbox \ Source \ PointOfSale \ PuntoVenta \ Presentation \ ListSalePresenter.cs 26 20 PuntoVenta.UI

even EntityListViewModel < IEntity>将始终为真。

public abstract class EntityListViewModel<TEntity> : ViewModelBase, IEntityListViewModel<TEntity> 
    where TEntity : class, IEntity 
{ 
    private BindingSource Entities { get; set; } 

    private string searchQuery = string.Empty; 

    public EntityListViewModel() 
    { 
     SearchQuery = string.Empty; 
     Entities = new BindingSource(); 
    } 

    public TEntity Selected 
    { 
     get { return Entities.Current as TEntity; } 
     set { Entities.Position = Entities.IndexOf(value); } 
    } 

    public string SearchQuery 
    { 
     get { return searchQuery; } 
     set 
     { 
      searchQuery = value; 
      NotifyProperty("SearchQuery"); 
     } 
    } 

    public List<TEntity> DataSource 
    { 
     set 
     { 
      Entities.DataSource = value; 
      NotifyProperty("DataSource"); 
     } 
    } 
} 

public interface IEntity 
{ 
    Guid Id { get; set; } 

    DateTime DateCreated { get; set; } 
    DateTime DateUpdated { get; set; } 
} 

public interface IListView<TModel> : IView<TModel> 
    where TModel : ViewModelBase 
{ 
    event EventHandler OnSearchQueryChanged; 
    event EventHandler OnSelectRequested; 
} 

public abstract class ViewModelBase : IModel 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void NotifyProperty(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

public class SaleListViewModel : EntityListViewModel<SaleView> 
{ 
    private bool _ShowPendingOnly = false; 

    public SaleListViewModel() 
    { 
    } 

    public bool ShowPendingOnly 
    { 
     get { return _ShowPendingOnly; } 
     set 
     { 
      _ShowPendingOnly = value; 
      NotifyProperty("ShowPendingOnly"); 
     } 
    } 

    public List<Customer> Customers { get; set; } 
} 

回答

1

避免对EntityListViewModel声明中使用泛型类型。

在这种情况下,不需要用泛型声明对象是否总是实现IEntity接口。

public abstract class EntityListViewModel 
         : ViewModelBase, IEntityListViewModel<IEntity> 

您还需要将此类中的任何引用更改为TEntity

public IEntity Selected 
{ 
    get { return Entities.Current as IEntity; } 
    set { Entities.Position = Entities.IndexOf(value); } 
} 

public List<IEntity> DataSource 
{ 
    set 
    { 
     Entities.DataSource = value; 
     NotifyProperty("DataSource"); 
    } 
} 

在这一点上,你可以声明ListPresenter作为

public abstract class ListPresenter<TView, TModel> 
         : Presenter<TView, TModel> 
           where TView : IListView<TModel> 
           where TModel : EntityListViewModel<IEntity> 
+0

EntityListViewModel具有使用泛型的此属性:public TEntity Selected { get {return Entities.Current as TEntity; } set {Entities.Position = Entities.IndexOf(value); } } – Marc

+0

它可以工作,但在这种情况下,我必须在每次使用Model.Selected属性时都投出类型 – Marc

+0

然后...您希望避免'get {return Entities.Current as IEntity; ''转换,不是吗? – HuorSwords

0

难道你们就不能只是限制IListViewEntityListViewModelIEntity

public abstract class ListPresenter<TView, TModel> : Presenter<TView, TModel> 
    where TView : IListView<IEntity> 
    where TModel : EntityListViewModel<IEntity> 

您可能需要做出IListViewEntityListViewModel协:

public interface IListView<out T> 
+0

这是我第一次尝试,但我得到的错误:类型“PuntoVenta.ViewModels.SaleListViewModel”不能用作类型参数泛型类型或方法'PuntoVenta.Presentation.ListPresenter '中的'TModel'。没有从'PuntoVenta.ViewModels.SaleListViewModel'到'PuntoVenta.ViewModels.EntityListViewModel '的隐式引用转换。 – Marc