我被我的继承卡住了:
首先让我解释我的问题的前提。我的模型:
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网站,我有那些基类,需要由所有其他视图模型显示/编辑一个人/超级英雄继承:
public class BasePersonViewModel
{
public string Name { get; set; }
ctors()
}
public class BaseSuperHeroViewModel : BasePersonViewModel
{
public List<string> SuperPowers{ get; set; }
ctors()
}
这里是我卡住的地方,我试图只定义一个ViewModel,无论Person和/或超级英雄(如果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);
}
}
虽然这可以工作,但使用起来真的不性感。在那之上,我可以有另一个ViewModel它也继承自SomeViewModel。
是否有更干净的方法来实现这一点?
编辑我的主要目标是能够根据一个基类来强制转换我的SomeViewModel。比如在我的控制器中输入:
if myclass is SomeViewModel (of type SuperHero)
如何为Person/super - hero数据库检索/检查
var data = context.Person.first(w=> w.Id==1)
if (data is SuperHero)
..
我想这样做,因为我想使用相同的视图模型比如列出超级英雄和人物,如果是超级英雄,显示方式会略有不同
编辑2 我尽量避免使用整个模型。对象能够直接看到它与模型…但是我越想越觉得这是不可能的…最重要的是,我想在SomeViewModel中扩展一些其他超级英雄特定的属性(仅当SomeViewModel是超级英雄时),这些属性没有在BaseSuperHeroModel中声明…假设在SomeViewModel中,我想要字段'ComesFromPlanet',只有当超级英雄。
编辑3 我想过另一种方法,但它显然创建了各种ViewModel。对于最一般的情况(所有Person共享的所有字段),我将保留base:
public class BasePersonViewModel
{
public string Name { get; set; }
ctors()
}
I接口指定Person:
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;}
}
这是一个干净的解决方案吗?
对不起,我肯定我不清楚这一点,但我尽量!
感谢您的投入和时间。
我试图只定义一个ViewModel,可以使用不管基类和访问属性的人和/或超级英雄(如果人是一个超级英雄)
假设当模型不是超级英雄时,您将返回超级英雄属性的默认值,您可以这样做:
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
}
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);}
}
}
因此,如果所有的people类都覆盖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; }
不管person的子类有多少