简体   繁体   English

初始化视图模型,该视图模型从基础模型继承并具有基础模型的值

[英]Initialise View Model that inherits from base model with values from base model

I have a function that returns Class1Model 我有一个返回Class1Model的函数

Class1Model model = GetClass1Model();

I also have a Class1ViewModel that inherits from Class1Model to which I have added some get only properties for formatting in a view. 我也有一个Class1ViewModel ,它继承自Class1Model ,我在其中添加了一些仅获取属性以在视图中进行格式化。

public class Class1ViewModel : Class1Model  
{
    public string MyFormattedProperty => $"{base.Height:###.00} x {base.Width:###.00}" 
}

So I was hoping that I could do this: 所以我希望我能做到这一点:

Class1Model model = GetClass1Model();
var viewModel = model as Class1ViewModel;

But this doesn't work 但这行不通

So how would this usually be done? 那么通常如何做呢?

I suggest a composition approach instead of inheritance. 我建议使用合成方法而不是继承。

class Class1Model
{
    // model properties
}

class Class1ViewModel
{
    public Class1ViewModel(Class1Model model)
    {
        _Model = model;
    }

    private Class1Model _Model;
    public Class1Model Model { get { return _Model; } }

    // viewmodel specific extensions

    public string MyFormattedProperty => $"{Model.Height:###.00} x {Model.Width:###.00}"
}

If you expect your model properties to change, you should subscribe to model property changes with some weak event listener and issue appropriate property changed events for dependent viewmodel properties. 如果您希望模型属性发生更改,则应该使用一些弱事件侦听器订阅模型属性更改,并为从属viewmodel属性发出适当的属性更改事件。

You are trying to cast an instance of the base type to the sub-type which is not allowed. 您正在尝试将基本类型的实例转换为不允许的子类型。

An Class1ViewModel is a Class1Model. Class1ViewModel是Class1Model。 Not the other way around. 并非相反。

So this would work: 所以这可以工作:

Class1ViewModel viewModel = new Class1ViewModel();
Class1Model model = viewModel;

In general it makes no sense (read this answer ), so I am not sure if providing general solution is a good idea. 通常,这没有任何意义(请阅读此答案 ),因此我不确定提供通用解决方案是否是一个好主意。

You can do surely have one, eg via cloning via serialization trick: 您肯定可以拥有一个,例如通过序列化技巧进行克隆:

using Newtonsoft.Json;

class Base
{
    public string A;
    public string B;
}

class Inherited : Base
{
    public string C = "c";
}

// in some method
var @base = new Base { A = "a", B = "b" };
var inherited = JsonConvert.DeserializeObject<Inherited>(JsonConvert.SerializeObject(@base));

inherited will have @base values (I used fields, should work for properties too) copied and own values will be default. inherited将复制@base值(我使用过的字段,也应该适用于属性),并且自己的值将是默认值。

This is very slow approach. 这是非常缓慢的方法。 Consider to use manual copy instead: 考虑改为使用手动复印:

var @base = new Base { A = "a", B = "b" };
var inherited = new Inherited { A = @base.A, B = @base.B, C = "whatever" };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM