我来到这里的课程看起来像这样:
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 }); ;
}
}
但这是一个整洁的设计吗?
答案 0 :(得分:4)
您应该使用SIBRegisterHardware2
类型的接口而不是抽象类。
而且你可以使用Covariance in Generics:
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();