你如何覆盖C#中的属性?

时间:2013-05-16 12:13:58

标签: c# inheritance

我有一个接口说 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";
        }
    }
}

6 个答案:

答案 0 :(得分: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#对比禁止这个。

答案 1 :(得分:1)

class A
{
    public virtual int P1
    {
        get { return 42; }
        set { }
    }
}

class B : A
{
    public override int P1
    {
        get { return 18; }
    }
}

答案 2 :(得分:1)

  

他们是否隐含公开?

接口memebers是implicity public,您可以在接口中使用任何访问说明符和接口成员。

interface C# - MSDN

  

接口成员自动公开,不能包含任何内容   访问修饰符。

评论:

  

我在谈论它抱怨我的实施课程   在我的IMyInterface.MyProperty

声明中使用public修饰符

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

请参阅此文章:Explicit interface implementation – to hide interface member in implementing type

  

要明确实现接口,请删除公共访问权限   说明符(所有接口成员都是公共的),并谓词方法   带有接口名称和点的名称

答案 3 :(得分:1)

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

你的第二个例子是明确的界面实现 - 它不能公开设计。只有当您的变量类型为IMyInterface时,您才能调用它。

你当然可以在实现类中将你的属性标记为virtual,以允许它在iheritting类中被覆盖,但这是另一个故事。

答案 4 :(得分:0)

这可能有助于Interface Properties (C# Programming Guide)

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

答案 5 :(得分:0)

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

即。通过陈述

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

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

更新

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

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