简体   繁体   中英

Initialise View Model that inherits from base model with values from base model

I have a function that returns 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.

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.

You are trying to cast an instance of the base type to the sub-type which is not allowed.

An Class1ViewModel is a 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.

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" };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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