2013-10-28 54 views
0

我來到這裏的一類,看起來像這樣:轉換對象一般抽象類

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

而且是一個利落的設計?

+2

'DeviceA'和'DeviceB'不是從'Device'的。此外,'Device'不是通用類型,您不能寫'Device '。我錯過了什麼嗎? – Dennis

+0

感謝您的提示。我添加了一個缺失的類.. – displayname

回答

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

UPDATE 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(); 
+0

這裏的問題是,'ISIBRegisterHardware2'不是'接口'。它是一個抽象類,它實現了一些方法。 – displayname

+0

什麼阻止你從基類中提取接口並使用接口? –

+0

我想在'ISIBRegisterHardware2'中實現一些方法,例如'public T open()',它將程序連接到插入計算機的設備。每個設備都以同樣的方式進行操作。唯一的區別是返回的設備類型(通用)。 – displayname