如何从可以由其他类继承的类继承并保留其他类属性(对于视图模型)

时间:2013-04-03 19:11:31

标签: c# oop viewmodel multiple-inheritance

我被遗忘在我的遗产中:

首先让我解释一下我的问题的前提。 我的模特:

public class Person
{      
    [Key]
    public int PersonId { get; set; }

    [MaxLength(100)]
    public string Name { get; set; }    
}

public class SuperHero:Person
{    
    [MaxLength(100)]
    public string SuperHeroName { get; set; }
    public virtual ICollection<SuperPower> SuperPowers{ get; set; }
}

现在,我正在尝试为我的MVC网站创建我的viewModel,我有那些需要由显示/编辑Person / SuperHero的所有其他viewmodel继承的基类:

public class BasePersonViewModel
{
    public string Name { get; set; }    
    ctors()
}

public class BaseSuperHeroViewModel : BasePersonViewModel
{
    public List<string> SuperPowers{ get; set; }
    ctors() 
}

这里是我被困的地方,我试图只定义一个ViewModel,它可以用于Person和/或SuperHero的基类和访问属性(如果Person是超级英雄)。我一直在拔头发,但到目前为止只找到了一个我不喜欢的解决方案:

示例:

public class SomeViewModel<T> where T : BasePersonViewModel
{
    public BasePersonViewModel obj;
    public DateTime BirthDate { get; set; }

    public SomeViewModel(Person data) //: base(data)
    {
        if (data is SuperHero)
            obj = new BaseSuperHeroViewModel (data);
        else
            obj = new BasePersonViewModel(data);
    }
}

虽然这样可行,但使用它真的不太性感。最重要的是,我可以拥有另一个继承自SomeViewModel的ViewModel。

有更清洁的方法来实现这一目标吗?

修改 我的主要目标是能够根据其中一个基类来转换我的SomeViewModel。让我们说在我的控制器中做一些事情:

if myclass is SomeViewModel (of type SuperHero)

究竟如何为Person / SuperHero数据库检索/检查

执行此操作
var data = context.Person.first(w=> w.Id==1)
if (data is SuperHero)
..

我想这样,因为我想使用相同的viewmodel让我们说列出超级英雄和人,如果它是超级英雄则只是略有不同

编辑2 我试图避免使用整个Model.Obj能够直接用模型看到它...但我想的越多,我就越认为这是不可能真的......最重要的是我会喜欢在SomeViewModel中扩展一些其他的superHero特定属性(仅当SomeViewModel是一个超级英雄),而不是在BaseSuperHeroModel中声明的...让我们说在SomeViewModel中我只想要超级英雄的字段'ComesFromPlanet'。

编辑3 我想到了另一种方法,但它显然创建了各种ViewModel。 对于最一般的情况(所有人共享的所有字段),我会保留我的基础:

public class BasePersonViewModel
{
    public string Name { get; set; }    
    ctors()
}

我界面特定的人:

public Interface IBaseSuperHero
{    
    [MaxLength(100)]
    public string SuperHeroName { get; set; }
    public List<string> SuperPowers{ get; set; }
}

我会像这样保留OtherViewModel:

public class SomeViewModel:BasePersonViewModel
{    
    Public datetime Birthdate {get;set;}
}

然后我会为其他Person继承者创建一个特定的SomeviewModel,并使用接口来获得旧属性和新属性。 例如:

public class SomeViewModelSuperHero:SomeViewModel, IBaseSuperHero
{   
  public string OriginalPlanet {get;set;}
}

这是一个干净的解决方案吗?

抱歉,我确定我不清楚这一点,但我试试了!

感谢您的投入和时间。

2 个答案:

答案 0 :(得分:1)

这样的东西
public class Person {
    public virtual BasePersonViewModel MainViewModel {
        get { return new BasePersonViewModel(this);}
    }
}

public class SuperHero : Person {
    public override BasePersonViewModel MainViewModel {
        get { return new BaseSuperHeroViewModel(this);}
    }
}

因此,如果所有人员类覆盖MainViewModel属性以返回相应的视图,则不需要

public BasePersonViewModel obj;
public SomeViewModel(Person data) {
    if (data is SuperHero)
        obj = new BaseSuperHeroViewModel (data);
    else
        obj = new BasePersonViewModel(data);
}

因为你可以拥有

public BasePersonViewModel obj;
public SomeViewModel(Person data) { obj = data.MainViewModel; }

然而,无论你有多少个人的子类,它都会有效。

答案 1 :(得分:1)

  

我试图只定义一个可以在Person和/或SuperHero的基类和访问属性中使用的ViewModel(如果Person是超级英雄)

假设当模型不是超级英雄时你会返回超级英雄属性的默认值,你可以这样做:

public class PersonOrSuperHeroViewModel {
  private Person person;
  private SuperHero superHero;

  public PersonOrSuperHeroViewModel(Person personOrSuperHero) {
    if (personOrSuperHero is SuperHero) superHero = personOrSuperHero;
    person = personOrSuperHero;
  }

  public IsSuperHero { get { return superHero != null; } }

  ... // super-hero properties only work when IsSuperHero == true
}