【问题标题】:C# Down casting Parent Object to SubclassesC#向下转换父对象到子类
【发布时间】:2018-11-24 17:24:44
【问题描述】:

我收到一个父对象(设备)列表,并希望将每个设备对象转换为子类对象。布局看起来类似于:

public class Device
{
    public string FimrwareVersion { get; set; }

    public string DeviceName { get; set; }

    public int Status { get; set; }

    public string Alias { get; set; }

    public string DeviceType { get; set; }

    public string AppServerUrl { get; set; }

    ...
}

public class SmartLightBulb : Device
{
    public string Model { get; set; }

    public string Description { get; set; }

    public string SoftwareVersion { get; set; }

    public int State { get; set; }

    // Turn On/Off
    public async Task ToggleState()
    {
        // Toggle State
    }

    ...
}


public class SmartPlug : Device
{
    public string Model { get; set; }

    public string Description { get; set; }

    public string SoftwareVersion { get; set; }

    public int State { get; set; }

    // stay on for X
    public async Task SetTimer()
    {
        // Set Timer
    }

    ...
}

public class Lb100 : SmartLightBulb 
{

    public async Task ChangeBrightness(int brightness)
    {
        // Change Brightness
    }
}

public class Lb200 : SmartLightBulb 
{

    public async Task ChangeBrightness(int brightness)
    {
        // Change Brightness
    }

    public async Task ChangeColor()
    {
        // Change Color
    }
}

问题是我收到了一个设备列表,我无法从设备向下转换到 Lb100。我希望 Lb100 维护从设备类接收到的所有属性,并使用 Lb100 的功能。我听说过反思,但我也听说这是一个非常缓慢的过程,应该尽可能避免。

如果我可以去,那就完美了:

var device = new Device(){ Firmware = "V1.4"...};
var lb100 = (Lb100) device;

我也明白无法向下转换的原因是因为在创建父对象时,它为该类型的对象分配了足够的内存。然后,当您尝试将其转换为更大的子类时,您就是在尝试将更大的子类放入分配的空间中。

从我收集的研究来看,编程时的这种思维方式是不正确的,但没有人真正提到过这个问题的正确思维方式。其他用户提到他们创建了一个构造函数,手动将每个属性设置为彼此相等;但这似乎是维护代码的主要麻烦,尤其是在添加更多设备和模型时。感谢您提供的任何建议!

【问题讨论】:

  • 采用基类实例的派生类构造函数是这样做的方法。
  • 您可以实现 IConvertable 以完成此操作。
  • 或者使用 Newtonsoft.Json 序列化/反序列化你的对象 var serialized = JsonConvert.SerializeObject(parent); var deserialized = JsonConvert.DeserializeObject<ChildType>(serialized);
  • 我认为您误解了面向对象编程中的多态性概念。我会从这里开始阅读

标签: c# casting type-conversion downcast


【解决方案1】:

你可以尝试转换为子类,你只需要验证它是否可以转换。

public class Program
{
    public static void Main(string[] args)
    {
        var smartLightBulb = new SmartLightBulb()
        {
            DeviceType = "deviceType",
            Model = "model"
        };
        Output(smartLightBulb);
    }

    public static void Output(Device device)
    {
        var smartLightBulb = (device as SmartLightBulb);
        if(smartLightBulb != null)
        {
            Console.WriteLine(smartLightBulb.Model);
        }
    }
}

public class Device
{
    public string DeviceType { get; set; }
}

public class SmartLightBulb : Device
{
    public string Model { get; set; }
}

【讨论】:

  • 您好安东尼奥,感谢您的快速回复!唯一的问题是,在您的示例中,您从 SmartLightBulb 开始,我很遗憾地从设备开始。您的解决方案确实让我更接近最终目标,因为它不再引发“无法从设备投射到 SmartLightBulb”异常。返回的新灯泡为空。再次感谢!
【解决方案2】:

您可以向下转换(从超级到父级),因为这只是删除字段。 例如。 lb100 是一种设备。

但是你不能向上转换(从父级到超级级),因为这需要额外的数据。 例如。设备不是 lb100 的类型。

【讨论】:

  • 您正在颠倒通常的术语。 Downcasting 通常是从派生程度较低的类型转换为派生程度更高的类型,这与您所说的相反。此外,在 C# 中,这种“强制转换”a) 不需要强制转换操作,并且 b) 实际上并不根本不改变表示。没有“删除”任何字段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
相关资源
最近更新 更多