首页 > 解决方案 > C#向下转换父对象到子类

问题描述

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

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;

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

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

标签: c#castingtype-conversiondowncast

解决方案


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

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

推荐阅读