1

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?

wingyip
  • 3,465
  • 2
  • 34
  • 52

3 Answers3

2

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.

grek40
  • 13,113
  • 1
  • 24
  • 50
0

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;
Skyuppercut
  • 332
  • 3
  • 14
  • It's true you can cast to base types, but this doesn't solve the problem in question, where a model is given first. – grek40 Nov 10 '17 at 14:22
  • The word "necessarily" isn't well chosen IMO. A base class is never one of its subclasses. There may be a conversion operator, but that's a distinct special case (and usually not considered a good use of a conversion operator). – 15ee8f99-57ff-4f92-890c-b56153 Nov 10 '17 at 14:23
  • well.. he needs to create a new instance of the sub type. I thought that was self-explanatory. – Skyuppercut Nov 10 '17 at 14:25
0

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, e.g. 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" };
Sinatr
  • 20,892
  • 15
  • 90
  • 319