English 中文(简体)
模拟继承和重复示范参考
原标题:viewmodel inheritance and duplicate model references

我的问题是: 如何管理 继承的一连串观景模型?

我的情况:

我有一个标准的“强” ViewModelBase

此外,我还有一个 " 强势 " 商业对象ViewModel

所有观景模型当然都包含一个模型对象(海关、雇员、人基)。

  • BusinessObjectViewModel inherits from ViewModelBase
  • PersonBaseViewModel inherits from BusinessObjectViewModel
  • CustomerViewModel inherits from PersonBaseViewModel
  • EmployeeViewModel inherits from PersonBaseViewModel

模型通过建筑师进入了观景模型。

如果我使用一个构建器链(每个视觉模型都呼叫基础构建器), 每个视觉模型都有它从模型中返回封装值的模型。

但我必须在每一个查看模型中都有一个模型属性。 在客户视图模型中,我可以用“强势” CustommerViewModel

或者我必须把所有地产 都投在上观的模特里

P. S. 这只是我模式等级制度的一个小插图

提前感谢。

最佳回答

如果BusinessObject and person classes(以及他们的 VM 类)是抽象的,

public abstract class BusinessObjectViewModel : ViewModelBase
{
    protected abstract BusinessObject BusinessObject { get; }

    protected BusinessObject Model { get { return this.BusinessObject; } }
}

public abstract class PersonViewModel : BusinessObjectViewModel
{
    protected abstract Person Person { get; }

    protected new Person Model { get { return this.Person; } }

    protected override sealed BusinessObject BusinessObject
    {
        get { return this.Model; }
    }
}

public class CustomerViewModel : PersonViewModel
{
    protected new Customer Model { get; set; }

    protected override sealed Person Person
    {
        get { return this.Model; }
    }
}

public class EmployeeViewModel : PersonViewModel
{
    protected new Employee Model { get; set; }

    protected override sealed Person Person
    {
        get { return this.Model; }
    }
}

这样,每个衍生的VM等级都通过实施抽象属性和隐藏基本等级的模型属性,为其基本VM模型属性提供价值,因此,每个VM等级都使用适当类型的模型属性(因此不需要铸件)。

这种办法的利弊在于:

效益:

  • No casting involved.

补缺 :

  • Works only if base classes (BusinessObjectViewModel and PersonViewModel) are abstract because there must exist an abstract property that is implemented by the derived class and provides a Model instance to these base classes.
  • Model property should not be accessed in the base class constructors, because constructor chaining goes from base class to the most derived class. The most derived class constructor will set Model, so base class constructors are called to early to see it. This can be avoided by passing Model as a parameter through constructors.
  • BusinessObject and Person properties are unnecessary seen by the derived classes. EditorBrowsableAttribute might help here for Intellisense, but only when code is used by another assembly in different Visual Studio solution (this is Visual Studio specific behavior).
  • Performance. When base classes access Model, code will go through a chain of virtual properties. But since since implemented abstract properties are marked as sealed, virtual table lookup should not be so much performance degrading.
  • Doesn t scale nicely. For deep class hierarchies code would contain many unnecessary members.

另一种办法是:

public class BusinessObjectViewModel : ViewModelBase
{
    protected BusinessObject Model { get; private set; }

    public BusinessObjectViewModel(BusinessObject model)
    {
        this.Model = model;
    }
}

public class PersonViewModel : BusinessObjectViewModel
{
    protected new Person Model { get { return (Person)base.Model; } }

    public PersonViewModel(Person model)
        : base(model)
    {
    }
}

public class CustomerViewModel : PersonViewModel
{
    protected new Customer Model { get { return (Customer)base.Model; } }

    public CustomerViewModel(Customer model)
        : base(model)
    {
    }
}

public class EmployeeViewModel : PersonViewModel
{
    protected new Employee Model { get { return (Employee)base.Model; } }

    public EmployeeViewModel(Employee model)
        : base(model)
    {
    }
}

效益:

  • Base classes do not need to be abstract.
  • Model can be accessed through base class constructors.
  • No unnecessary additional properties.

补缺 :

  • Casting.

基于这一分析,我将采用第二种选择,因为纠正其唯一的缺点,即铸造性能,将是不必要的微优化,在WPF中将不明显。

问题回答

海事组织最简单的答案是使用通用标准,这些标准可能与

public abstract class ViewModelBase<TModel>  TModel : class{
    public TModel Model { get; protected set; }
}

. net 打字系统将知道您的 TModel 是个人,客户, 或其他任何没有铸造的东西。

如果需要更多,或者你想发布一些需要帮助的代码,请告诉我。 是的,一开始,获得你的超级型继承人 可能会很困难。

HTH,
Berryl

如果您只想在视图模式中显示您的模型属性, 那么您不需要在视图模式中重新声明模型属性以暴露这些属性。 我通常会在我的视图模式中将模型基本对象作为属性曝光。 在您的例子中, 比如在您的员工View模式中, 您将会有一个 :

private Employee _MyEmployee;
public Employee MyEmployee {
get
{
return _MyEmployee;
}
set
{
_MyEmployee = value;
NotifyPropertyChanged(x=>x.MyEmployee);
}

您的视图可以通过在视图模式中曝光的 MyEmployer 属性与您的员工属性捆绑。 据我理解,您想要在 VM 中重新声明或包扎您的模型属性, 唯一的一个案例就是您需要做一些数据操作才能显示到您视图中 。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签