首页 文章

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

提问于
浏览
2

我有一个接口说 IMyInterface 这是由类_290167实现的_如何用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

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

    您在使用 class inheritance 时覆盖 . 您需要在基类中创建它们 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; }
    }
    

    如果你 explicitly implement an interface ,则不需要 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#禁止这样做 .

  • 5

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

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

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

  • 1

    他们是否隐含公开?

    接口成员是隐含的 public ,您可以在接口中使用任何访问说明符和接口成员 .

    interface C# - MSDN

    界面成员自动公开,并且不能包含任何访问修饰符 .

    评论:

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

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

    看这篇文章:Explicit interface implementation – to hide interface member in implementing type

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

  • 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;
    }
    }
    
  • 1
    class A
    {
        public virtual int P1
        {
            get { return 42; }
            set { }
        }
    }
    
    class B : A
    {
        public override int P1
        {
            get { return 18; }
        }
    }
    
  • 1

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

    即陈述

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

相关问题