2014-02-20 43 views
7

我寫了一些使用Sharp Develop IDE轉換爲C#的VB代碼。 我定義了一個接口,IElement,它由返回自己的XML表示的對象實現。任何實現這個接口的對象都應該能夠返回它的TagName和它的XML字符串表示。爲了得到它的XML字符串,它可能需要遍歷它的子/集合集合來獲取其所有子對象的XML表示。無法實現接口成員,因爲它不是公開的

從Element繼承的類可以使用其基類的GetXml和GetNestedXml或選擇覆蓋它,但GetNestedXml函數不需要是公共的,因爲它只能從派生類的公共GetXml函數中調用。因此,在原始的VB版本中,GetNestedXML的範圍被設置爲受保護的。然而,夏普發展和我有問題試圖將此代碼轉換爲C#。請參閱下面的錯誤。

在附註中,我確實意識到可能有更好的方法來實現這一點,我會對易於着火的建議感興趣。 :-) 謝謝。

Public Interface IElement 

    ReadOnly Property TagName() As String 
    ReadOnly Property GetXml(Optional ByVal targetXml As Integer = TargetXmlEnum.All) As String 
    Function GetNestedXml() As String 

End Interface 


Public Class Element 

    Implements IElement 

    Public ReadOnly Property TagName() As String Implements IElement.TagName 
     Get 
      '.... 
     End Get 
    End Property 

    Public Overridable ReadOnly Property GetXml(Optional ByVal targetXml As Integer = TargetXmlEnum.All) _ 
      As String Implements IElement.GetXml 
     Get 
      '.... 
     End Get 
    End Property 

    Protected Overridable Function GetNestedXml() As String Implements IElement.GetNestedXml 
     '.... 
    End Function 

End Class 

轉換C#:

public interface IElement 
{ 

    string TagName { get; } 
    string GetXml { get; } 
    string GetNestedXml(); 

} 

public class Element : IElement 
{ 
    public string TagName { 
     get { //... } 
    } 

    public virtual string GetXml 
    { 
     get 
     { 
      //... 
     } 
    } 

    protected virtual string GetNestedXml() 
    { 
     //... 
    } 
} 

錯誤:

Error 1 'Smit.SpreadsheetML.Element' does not implement interface member 'Smit.SpreadsheetML.IElement.GetNestedXml()'. 'Smit.SpreadsheetML.Element.GetNestedXml()' cannot implement an interface member because it is not public. D:\Users\Chad\Desktop\SMIT\SMIT.SpreadsheetML.ConvertedToC#\Element.cs 41 24 Smit.SpreadsheetML.Converted 
+0

是啊,我沒有嘗試,但錯誤依然存在。無論如何,即使它沒有解決問題,它似乎也值得添加。謝謝。 – ChadD

+0

只需刪除「受保護的虛擬字符串GetNestedXml()」實現 –

+1

@MilanRaval它會給虛擬部分的錯誤,如果保護被刪除。 –

回答

1

解決此問題的快速方法是使GetNestedXml公開。如果你不想要這個,你也可以在抽象基類中聲明GetNestedXml作爲受保護的抽象方法。但這意味着所有的類都需要從這個基類派生並實現該方法。如果你想在基類中提供一個實現,你也可以使該方法是虛擬的,這樣派生類可以但不一定需要覆蓋它。爲了實現這一點,請執行以下步驟:

  1. 創建一個新的抽象基類。
  2. 添加受保護的GetNestedXml()的抽象/虛擬實現。如果它是虛擬的,那麼也提供一個方法體(並且你不需要將這個類抽象化)。
  3. 從界面中刪除該方法。
  4. 從基類中派生實現接口的所有類(並且希望獲得基本實現GetNestedXml的舒適性)。

隱藏該方法的另一種方法是顯式實現IElement,以便調用者只有在他們使用接口訪問對象時才能看到它。

+0

我不希望公開它,並且使GetNestedXml函數抽象意味着繼承分類被迫實現它們自己的函數版本,即使基類的版本已經足夠。我希望繼承的類可以選擇是否要使用基類或重寫它。 – ChadD

+0

@ChadD:如果所有類都必須從基類派生的事實在您的場景中可以使用,那麼這是最好的解決方案。您不需要使方法抽象化。您也可以使其變爲虛擬並提供派生類可以根據需要重寫的基本實現。 – Markus

+0

我錯過了我需要做的事情來做到這一點。我認爲這就是我在VB版本中所做的。我確實讓它變得虛擬並提供了一個基礎實現。但是,我不希望它是公開的,只能從子類訪問,因此受到保護。 – ChadD

4

作爲接口的實現需要是公共的或明確的:

變化這種方法

protected virtual string GetNestedXml() 
{ 
    //... 
} 

protected virtual string IElement.GetNestedXml() 
{ 
    //... 
} 

編輯

創建這樣一個接口:

public interface IElement 
{ 
    string TagName { get; } 
    string GetXml { get; } 
} 

創建一個抽象基類這樣

abstract class ElementBase:IElement 

{ 
    public abstract string TagName { get; } 
    public abstract string GetXml { get; } 
    protected abstract string GetNestedXml(); 
} 

Impele元素類

public class Element : ElementBase 
{ 
    public override string TagName { 
     get { //... } 
    } 

    public override string GetXml 
    { 
     get 
     { 
      //... 
     } 
    } 

    protected override string GetNestedXml() 
    { 
     //... 
    } 
} 
+0

當我試圖在SO上研究這個錯誤時,我試着沒有完全理解它,看看錯誤是否首先消失。它沒。我得到了兩個錯誤,都提到了變化的行:修飾符'保護'是無效的這個項目\t 修飾符'虛擬'是無效的這個項目 – ChadD

+0

@ChadD檢查我編輯在asnwer,我希望它現在可以幫助你 –

+0

是的,幾個答案似乎現在排隊,所以我很難選擇「的」答案。感謝所有 – ChadD

0

問題是,當你聲明Element implements IElement你說:「嘿,我知道如何讓我的嵌套的XML,並且每個人都可以使用它!(public ...)」。

在你的班級GetNestedXml受保護,即你沒有履行你的聲明。
即使你做了一個明確的protected實現:

protected override string IElement.GetNestedXml() 
    { 
     //Implementation... 
    } 

在幕後,它仍然會實際上be public

+0

這聽起來像你在暗示Saghir A. Khatri寫了些什麼。如果是這樣,請參閱我的評論回覆。 – ChadD

+1

@ChadD他的編輯是正確的。另一件事,沒有足夠的關於'GetNestedXml'用法的信息。如果它是某些類的期望行爲,無論它們的繼承樹如何,Interface都是可行的。如果預期這種行爲來自特定的繼承樹,那麼使用'abstract'就是要走的路。此外,你可能想看看'ixmlserializable'這可能會有所幫助... –

3

一個接口聲明其所有繼承實例的責任。所以你不能使用not-public方法來實現你的接口方法。

如果由於其他原因而非公開,我建議您可以使用抽象類並使用抽象/虛擬方法來聲明它。

這樣的抽象方法:

public interface IElement 
{ 
    string TagName { get; } 
    string GetXml { get; } 
} 

public abstract class ElementBase : IElement 
{ 
    public string TagName { get; private set; } 
    public string GetXml { get; private set; } 
    protected abstract string GetNestedXml(); 
} 

虛方法:

public interface IElement 
{ 
    string TagName { get; } 
    string GetXml { get; } 
} 

public abstract class ElementBase : IElement 
{ 
    public string TagName { get; private set; } 
    public string GetXml { get; private set; } 

    protected virtual string GetNestedXml() 
    { 
     throw new NotImplementedException(); 
    } 
} 
相關問題