C# 使用基础模型的值初始化从基础模型继承的视图模型

C# 使用基础模型的值初始化从基础模型继承的视图模型,c#,C#,我有一个返回classmodel Class1Model model = GetClass1Model(); 我还有一个继承自classmodel的classviewmodel,我在其中添加了一些用于在视图中格式化的get-only属性 public class Class1ViewModel : Class1Model { public string MyFormattedProperty => $"{base.Height:###.00} x {base.Width:##

我有一个返回
classmodel

Class1Model model = GetClass1Model();
我还有一个继承自
classmodel
classviewmodel
,我在其中添加了一些用于在视图中格式化的get-only属性

public class Class1ViewModel : Class1Model  
{
    public string MyFormattedProperty => $"{base.Height:###.00} x {base.Width:###.00}" 
}
所以我希望我能做到这一点:

Class1Model model = GetClass1Model();
var viewModel = model as Class1ViewModel;
但这不起作用


那么这通常是如何实现的呢?

您正在尝试将基类型的实例强制转换为不允许的子类型

ClassViewModel是ClassModel。而不是相反

因此,这将起作用:

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

我建议采用组合方法而不是继承方法

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

如果您希望模型属性发生更改,则应使用一些弱事件侦听器订阅模型属性更改,并为从属viewmodel属性发出相应的属性更改事件。

一般来说,这没有意义(请阅读),因此我不确定提供通用解决方案是否是一个好主意

您当然可以拥有一个,例如,通过序列化技巧克隆:

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));

您的对象不是
classViewModel
。这是一款
class1型号
。如果你想要一个
classViewModel
,你需要从你的方法中返回一个。合成而不是继承?听起来像克隆。序列化基类,反序列化为继承的。组合?这是否意味着通过构造函数将模型传递给viewmodel,并在viewmodel上初始化model类型的属性?以及@Sinatr,克隆将如何工作?确实可以强制转换为基类型,但这并不能解决问题,因为首先给出了模型。单词“必然”基类从来不是它的子类之一。可能会有一个转换运算符,但这是一个明显的特殊情况(通常认为转换运算符的使用不好)。。他需要创建子类型的新实例。我认为这是不言自明的。
var @base = new Base { A = "a", B = "b" };
var inherited = new Inherited { A = @base.A, B = @base.B, C = "whatever" };