【问题标题】:Inheritance generic-class from non-generic interface从非泛型接口继承泛型类
【发布时间】:2017-02-06 11:27:49
【问题描述】:

我有模型类和接口:

public interface IEntity
{
    int ID { get; set; }
}

public class Entity : IEntity
{
    public int ID { get; set; }
}

我有 ViewModel 接口:

public interface IEntityListViewModel
{
    RangeObservableCollection<IEntity> Items { get; set; }
    IEntity SelectedItem { get; set; }

    void LoadItems();
}

我需要一个 ViewModel 基类:

public abstract class EntityListViewModel<T> : IEntityListViewModel where T :  IEntity
{
    public RangeObservableCollection<T> Items { get; set; }
    public T SelectedItem { get; set; }

    public EntityListViewModel()
    {
        Items = new RangeObservableCollection<T>();
    }

    protected abstract List<T> GetEntities();

    public void LoadItems()
    {
        var lst = GetEntities();
        Items.ReplaceRange(lst);
    }
}

当然,编译器需要IEntityListViewModel.Items的实现!

我能做到:

public interface IEntityListViewModel<T> where T : IEntity
{
    RangeObservableCollection<T> Items { get; set; }
    T SelectedItem { get; set; }

    void LoadItems();
}

但我还有一门课:

public abstract class UserControlBase : UserControl
{
    public IEntityListViewModel VM { get; set; }        

    public virtual void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        VM.LoadItems();
    }        
}

我需要UserControlBase,因为我的 ViewModel 有很多事件,并且我想在UserControlBase 中订阅它们。 我可以这样做:

public IEntityListViewModel<T> VM { get; set; }

但是我必须有UserControlBase&lt;T&gt;。我不喜欢这样。

如何从IEntityListViewModel 继承EntityListViewModel&lt;T&gt;?还是有其他解决办法?

【问题讨论】:

    标签: c# .net generics inheritance


    【解决方案1】:

    你可以这样做

    RangeObservableCollection<IEntity> IEntityListViewModel.Items
        {
            get
            {
                return new RangeObservableCollection<IEntity>(Items.Cast<IEntity>());
            }
    
            set
            {
                Items = new RangeObservableCollection<T>(value.Cast<T>());
            }
        }
    
        IEntity IEntityListViewModel.SelectedItem
        {
            get
            {
                return SelectedItem;
            }
    
            set
            {
                SelectedItem = (T)value;
            }
        }
    

    为了避免每次您需要更改为IEnumerable&lt;T&gt; 时都必须创建新的 RangeObservableCollection。另一个问题是,一直进行演员阵容可能会变得昂贵。此外,您没有提到前端将绑定哪个集合(我假设您将要这样做),因为可以进行一些优化。

    【讨论】:

      【解决方案2】:

      我对这个问题有点困惑,但我会尝试回答。

      如何从 IEntityListViewModel 继承 EntityListViewModel

      根据代码,我认为这就是你想要的

      public abstract class EntityListViewModel<T> where T : IEntity, EntityListViewModel
      

      这是实现您的目标最简单的方法,而无需强制您在 UserControlBase 类中实现泛型。

      【讨论】:

      • 我还没上课EntityListViewModel。这是什么?
      • 那是接口IEntityListViewModel,错字:)
      猜你喜欢
      • 2020-03-02
      • 2014-03-05
      • 2019-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-11
      • 1970-01-01
      相关资源
      最近更新 更多