2

我有一个接口说IMyInterface它由类MyClass实现我如何使用覆盖而不是屏蔽接口中的 getter 和 setter 声明属性?

以接口为例:

public interface IMyInterface
{
    String MyProperty {get;}
}

如果我这样做,我将隐藏接口属性

public class MyClass : IMyInterface
{
    public String MyProperty 
    { 
        get 
        {
             return "Whatever";
        }
    }
}

但如果我这样做,我会收到一条错误消息,指出MyProperty不能公开:

public class MyClass : IMyInterface
{
    public String IMyInterface.MyProperty 
    { 
        get 
        {
             return "Whatever";
        }
    }
}
4

6 回答 6

5

由于接口没有实现,覆盖是一个不适用于接口的概念。因此接口成员不需要是virtual.

您在使用类继承时覆盖。您需要virtual在基类中创建它们,并override在子类中使用关键字:

interface IFoo
{
    string Bar { get; }
}

class FooBase : IFoo
{
    public virtual string Bar { get; protected set; }
}

class Foo : FooBase
{
    public override string Bar { get; protected set; }
}

如果显式实现接口,则不需要public修饰符,因为该成员仅在使用者使用接口类型时可见:

class FooExplicit : IFoo
{
    // IFoo f = new FooExplicit(); <- Bar is visible
    // FooExplicit fe = new FooExplicit(); <- there is no Bar
    string IFoo.Bar { get; private set; }
}

由于IFoo.Bar仍然仅与接口相关联,因此它仍然是隐式的public。在 Java 中,您可以根据需要添加public修饰符(当然是可选的)。相比之下,C#禁止这样做。

于 2013-05-16T12:16:16.400 回答
1
class A
{
    public virtual int P1
    {
        get { return 42; }
        set { }
    }
}

class B : A
{
    public override int P1
    {
        get { return 18; }
    }
}
于 2013-05-16T12:17:31.773 回答
1

那么它们是否隐含地公开?

接口成员是隐式的public,您可以使用任何访问说明符与接口中的接口成员。

接口 C# - MSDN

接口成员是自动公开的,它们不能包含任何访问修饰符。

评论:

我说的是实现类,它抱怨我在 IMyInterface.MyProperty 声明中使用 public 修饰符

由于您正在进行显式接口实现,该方法只能针对接口对象调用,不能针对类对象调用。由于 interface 的所有成员都是隐式的public,这将是多余的,这就是为什么不允许。

见这篇文章:显式接口实现——在实现类型中隐藏接口成员

要显式实现接口,请删除公共访问说明符(所有接口成员都是公共的),并使用接口名称和点来谓词方法名称

于 2013-05-16T12:19:35.707 回答
1

你说的隐藏是什么意思?您的第一个示例是接口属性的正常隐式实现。您不是在隐藏它,而是在实施它。

您的第二个示例是显式接口实现 - 它不能按设计公开。只有当您的变量类型为 时,您才能调用它IMyInterface

您当然可以将您的属性标记为virtual实现类,以允许在继承类中覆盖它,但这是另一回事。

于 2013-05-16T12:19:51.380 回答
0

这可能有助于接口属性(C# 编程指南)

interface IEmployee{
string Name
{
    get;
    set;
}

int Counter
{
    get;
}}     
public class Employee : IEmployee    
{
public static int numberOfEmployees;

private string name;
public string Name  // read-write instance property
{
    get
    {
        return name;
    }
    set
    {
        name = value;
    }
}

private int counter;
public int Counter  // read-only instance property
{
    get
    {
        return counter;
    }
}

public Employee()  // constructor
{
    counter = ++counter + numberOfEmployees;
}
}
于 2013-05-16T12:16:49.757 回答
0

在接口中声明属性实际上并不提供接口上属性的实现。

即通过说明

public interface IMyInterface
...
    String MyProperty {get;}

实际上,您只是要求接口的实现必须提供一个MyProperty具有 getter 的属性。但是我同意语法很容易与自动属性混淆,但在接口的情况下,没有支持字段。

更新

显式接口实现用于区分多个接口需要相同属性名称的情况。可能以下内容澄清了这一点?

public interface IMyInterface
{
    String MyProperty { get; }
}

public interface IMyInterface2
{
    String MyProperty { get; }
}

// Implement BOTH interfaces explicitly
public class MyClass : IMyInterface, IMyInterface2
{
    string IMyInterface.MyProperty
    {
        get { return "I am Interface1.MyProperty"; }
    }
    string IMyInterface2.MyProperty
    {
        get { return "I am Interface2.MyProperty"; }
    }
    // Same Property Name on the class itself
    public String MyProperty
    {
        get { return "I am a brand new Property!"; }
    }
}

  // Which can be used like so:
  var myClass = new MyClass();
  Console.WriteLine(((IMyInterface)myClass).MyProperty);
  Console.WriteLine(((IMyInterface2)myClass).MyProperty);
  Console.WriteLine(myClass.MyProperty);


'I am Interface1.MyProperty'
'I am Interface2.MyProperty'
'I am a brand new Property!'


// Implement BOTH interfaces - just the one explicitly
public class MyClass : IMyInterface, IMyInterface2
{
    public string MyProperty
    {
        get { return "I am Interface1.MyProperty, exposed publicly"; }
    }
    string IMyInterface2.MyProperty
    {
        get { return "I am Interface2.MyProperty"; }
    }
}
于 2013-05-16T12:18:04.637 回答