将对象转换为泛型抽象类

本文关键字:泛型 抽象类 转换 对象 | 更新日期: 2023-09-27 18:37:08

我在这里得到了一个看起来像这样的类:

public abstract class SIBRegisterHardware2<T> : Register.IRegisterHardware<UInt16, UInt16> where T : IDevice
{
    protected T open()
    {
       // connect to server and return device T 
    }
    // ..
}
public class Device : SIBRegisterHardware2<IDevice>
{
    // ..
}

和一些派生类:

internal class DeviceA: SIBRegisterHardware2<IDeviceA>
{
}
internal class DeviceB: SIBRegisterHardware2<IDeviceB>
{
}

现在我正在寻找一种解决方案,可以让我这样做:

if(createDevA == true) {
  Device<IDevice> devHandle = new DeviceA();
} else {
  Device<IDevice> devHandle = new DeviceB():
}

问题是这样的代码会产生这样的错误:

Cannot implicitly convert type 'DeviceA' to 'SIBRegisterHardware2<IDevice>'

有没有办法让我抽象这样的模板?


我尝试过创建另一个与反射一起工作的类:

public class DeviceX : SIBRegisterHardware2<IDevice>
{
    private Register.IRegisterHardware<UInt16, UInt16> device = null;
    private Type deviceType = null;
    public DeviceX (String hwInterfaceClassName)
    {
        if (hwInterfaceClassName.Equals("DeviceA")) {
            device = new DeviceA();
            deviceType = device.GetType();
        }
        else if (hwInterfaceClassName.Equals("DeviceB")) {
            device = new DeviceB();
            deviceType = device.GetType();
        }
    }
    public override String doSomething(int param)
    {
        return (String)deviceType.GetMethod("doSomething").Invoke(device, new object[] { param }); ;
    }
}

但这是一个整洁的设计吗?

将对象转换为泛型抽象类

对于SIBRegisterHardware2类型,您应该使用接口而不是抽象类。而且你可以在泛型中使用协方差:

public interface IDevice { }
public interface IDeviceA : IDevice { }
public interface IDeviceB : IDevice { }
public interface ISIBRegisterHardware2<out T> where T : class, IDevice
{
    void DoSomething();
}
internal class DeviceA : ISIBRegisterHardware2<IDeviceA>
{
    //...
}
internal class DeviceB : ISIBRegisterHardware2<IDeviceB>
{
    //...
}
if (createDevA == true)
{
    ISIBRegisterHardware2<IDevice> devHandle = new DeviceA();
}
else
{
    ISIBRegisterHardware2<IDevice> devHandle = new DeviceB();
}

更新 0

public interface ISIBRegisterHardware2<out T> : Register.IRegisterHardware<UInt16, UInt16> where T : class, IDevice
{
    T Open();
}
public abstract class SIBRegisterHardware2<T> : ISIBRegisterHardware2<T> where T : class, IDevice
{
    T ISIBRegisterHardware2<T>.Open()
    {
        return OpenInternal();
    }
    protected virtual T OpenInternal()
    {
        //Common logic to open.
    }
}
internal class DeviceA : SIBRegisterHardware2<IDeviceA>
{
    //...
}
internal class DeviceB : SIBRegisterHardware2<IDeviceB>
{
    //...
}
ISIBRegisterHardware2<IDevice> devHandle;
if (createDevA == true)
{
    devHandle = new DeviceA();
}
else
{
    devHandle = new DeviceB();
}
devHandle.Open();