2014-11-17 317 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