2012-08-03 38 views
7

我目前正在開發一個二進制應用程序協議庫。 下面的代碼示例不編譯(靜態方法的定義不是抽象類型允許太糟糕了:(。),但顯示我的本意:無法在抽象類型中定義靜態方法。如何工作?

public abstract class CmdBody<T> 
{ 
    public static abstract byte[] ToBytes(T cmdBody); 
    public abstract int GetLength(); 
} 

public class CmdBodyA : CmdBody<CmdBodyA> 
{ 
    static override byte[] ToBytes(CmdBodyA cmdBody) 
    { // Implementation } 
} 

public class CmdBodyB : CmdBody<CmdBodyB> 
{ 
    static override byte[] ToBytes(CmdBodyB cmdBody) 
    { // Implementation } 
} 

[...] 

public class Cmd<T> 
{ 
    public CmdHeader Header { get; set; } 
    public CmdBody<T> Body { get; set; } 

    public byte[] ToBytes() 
    { 
     byte[] cmdBytes = new byte[Header.GetLength() + Body.GetLength()]; 
     Header.ToBytes().CopyTo(cmdBytes, 0); 
     Body.ToBytes().CoptyTo(cmdBytes, Header.GetLength()); 

     return cmdBytes; 
    } 
} 

所以很基本的東西,一個cmd由一個頭和主體的,根據Cmd類型,所有Cmd(s)和Body具有不同參數(屬性)的頭部類型是通用的,我想使用Cmd對象,並且能夠在它們上調用ToBytes()以發送它們

在我真正的實現中,我使用的是轉換運算符而不是ToBytes()方法,但我希望保持代碼示例的簡單性,最終它可以完成相同的工作

我有很多不同的命令類型,我不能找出一個解決方案來保持它簡單並實現我想要的只是一個通用的Cmd類型。 我能想到的唯一解決方案是擺脫基本CmdBody類中的靜態方法,擺脫通用方面,併爲每個CmdBody類型製作相關的Cmd類(類CmdA,類CmdB ...),但這將在一天結束時導致大量的代碼重複。

任何想法都可以幫助我在此工作?

+0

是否有可能你正在尋找一個接口,而不是抽象類型?抽象類型用於定義從其繼承的類,其中接口用於定義要實現的類所需的方法和字段。 – Codeman 2012-08-03 18:25:00

+0

這裏沒關係。接口或抽象類不能定義靜態方法,設計問題仍然存在。 – darkey 2012-08-03 18:26:19

+0

= /不能在抽象類上實現靜態方法。 (一個靜態成員不能被標記爲重載,虛擬或抽象) – marcoaoteixeira 2012-08-03 18:27:55

回答

13

您不能擁有「虛擬」靜態方法,因爲虛擬/抽象/覆蓋表明實例在運行時被覆蓋。

你可以做這樣的事情,但是:

public abstract class CmdBody 
{ 
    public static byte[] ToBytes<T>(T cmdBody) where T : CmdBody 
    { 
     return cmdBody.ToBytes(); 
    } 

    protected abstract byte[] ToBytes(); 

    public abstract int GetLength(); 
} 

public class CmdBodyA : CmdBody 
{ 
    protected override byte[] ToBytes() 
    { // Implementation } 
} 

public class CmdBodyB : CmdBody 
{ 
    protected override byte[] ToBytes() 
    { // Implementation } 
} 

這使得每個「CmdBody」類型來定義它是如何序列化本身,而是基類的靜態方法是訪問它唯一公開可見的方式。

這就是說,根據您的使用情況,根本沒有理由使這種靜態。你可以這樣做:

public abstract class CmdBody 
{ 
    public abstract byte[] ToBytes(); 

    public abstract int GetLength(); 
} 

public class CmdBodyA : CmdBody 
{ 
    public override byte[] ToBytes() 
    { // Implementation } 
} 

public class CmdBodyB : CmdBody 
{ 
    public override byte[] ToBytes() 
    { // Implementation } 
} 


public class Cmd<T> where T : CmdBody 
{ 
    public CmdHeader Header { get; set; } 
    public T Body { get; set; } 

    public byte[] ToBytes() 
    { 
     byte[] cmdBytes = new byte[Header.GetLength() + Body.GetLength()]; 
     Header.ToBytes().CopyTo(cmdBytes, 0); 
     Body.ToBytes().CopyTo(cmdBytes, Header.GetLength()); 

     return cmdBytes; 
    } 
} 
+0

Woooo!第一個代碼示例中非常好的工作。性感的東西:)而且非常感謝你的第二個建議(你應該編輯它以去除CmdBody中的ToBytes()定義中的一個)。非常感謝 ! – darkey 2012-08-03 18:35:37

+0

@darkey修復ToBytes的東西... – 2012-08-03 19:31:09

相關問題