无法实现接口成员,因为它不是公共的

Cha*_*adD 6 c#

我写了一些VB代码,我使用Sharp Develop IDE转换为C#.我定义了一个接口,IElement它由返回自身XML表示的对象实现.实现此接口的任何对象都应该能够返回其TagName及其XML字符串表示形式.要获取它的XML字符串,它可能必须遍历其子/嵌套集合以获取其所有子对象的XML表示.

从Element继承的类可以使用其基类的GetXml和GetNestedXml,或者选择覆盖它,但GetNestedXml函数不需要是公共的,因为它只能从派生类的公共GetXml函数调用.因此,在原始VB版本中,GetNestedXML的范围设置为protected.但是,Sharp Develop和我在尝试将此代码转换为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
Run Code Online (Sandbox Code Playgroud)

转换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()
    {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

错误:

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
Run Code Online (Sandbox Code Playgroud)

Sag*_*tri 5

由于接口实现需要是公共的或显式的:

改变这个方法

protected virtual string GetNestedXml()
{
     //...
}
Run Code Online (Sandbox Code Playgroud)

protected virtual string IElement.GetNestedXml()
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

编辑

创建一个像这样的接口:

public interface IElement
{
    string TagName { get; }
    string GetXml { get; }
}
Run Code Online (Sandbox Code Playgroud)

像这样创建一个抽象基类

abstract class ElementBase:IElement

{
    public abstract string TagName { get; }
    public abstract string GetXml { get; }
    protected abstract string GetNestedXml();
}
Run Code Online (Sandbox Code Playgroud)

实现您的 Element 类

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

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

    protected override string GetNestedXml()
    {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*kus 1

解决此问题的快速方法是将 GetNestedXml 公开。如果您不希望这样,还可以将 GetNestedXml 声明为抽象基类中的受保护抽象方法。但这意味着所有类都需要从这个基类派生并实现该方法。如果要在基类中提供实现,还可以将该方法设为虚拟,以便派生类可以但不一定需要重写它。为了实现此目的,请执行以下步骤:

  1. 创建一个新的抽象基类。
  2. 添加 GetNestedXml() 的受保护抽象/虚拟实现。如果它是虚拟的,还提供一个方法体(并且不需要使类抽象)。
  3. 从接口中删除该方法。
  4. 从基类派生实现该接口的所有类(并且希望获得基本实现 GetNestedXml 的便利)。

隐藏该方法的另一种方法是显式实现 IElement,以便调用者仅在使用接口访问对象时才能看到它。