Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中重写属性?_C#_Inheritance - Fatal编程技术网

如何在C#中重写属性?

如何在C#中重写属性?,c#,inheritance,C#,Inheritance,我有一个接口,比如说IMyInterface,它是由一个类MyClass实现的。我如何用getter和setter声明属性,这些getter和setter覆盖而不是屏蔽接口中的属性 例如,对于接口: public interface IMyInterface { String MyProperty {get;} } 如果我这样做,我就隐藏了接口属性 public class MyClass : IMyInterface { public String MyProperty

我有一个接口,比如说IMyInterface,它是由一个类MyClass实现的。我如何用getter和setter声明属性,这些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";
        }
    }
}

由于接口没有实现,重写是一个不适用于接口的概念。因此,接口成员不需要是虚拟的

使用类继承时可以重写。您需要在基类中使它们
虚拟
,并在子类中使用
覆盖
关键字:

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; }
}
如果显式实现接口,则不需要
公共
修饰符,因为该成员仅在使用者使用接口类型时可见:

class FooExplicit : IFoo
{
    // IFoo f = new FooExplicit(); <- Bar is visible
    // FooExplicit fe = new FooExplicit(); <- there is no Bar
    string IFoo.Bar { get; private set; }
}
类foopexplicit:IFoo { //IFoo f=new foopexplicit();这可能会有所帮助


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

i、 e.声明

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

那么,它们是否隐式公开

接口成员是隐式
公共的
,您可以对接口中的接口成员使用任何访问说明符

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

请评论:

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

因为您正在这样做,所以只能对接口对象调用该方法,而不能对类对象调用该方法。因为接口的所有成员都是隐式的
public
,所以它是多余的,这就是为什么不允许的原因

见本文:

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


隐藏是什么意思?您的第一个示例是接口属性的普通隐式实现。您不是隐藏它,而是实现它

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


当然,你可以在实现类中将你的属性标记为
virtual
,以允许它在iHerting类中被重写,但那是另一回事。

当显式实现接口成员时,你不使用可访问性修饰符。我不确定你的意思,我想这是接口应该做的,然后它们隐式地tly public?接口成员对于接口是公共的。当您显式实现它们时,它们只能通过接口访问。请参阅规范。@OmarKooheji我想这应该可以帮助您解决它们在接口中不是隐式虚拟的吗?我不是在创建抽象类。实际上,您不能重写接口成员,而只能基类成员。你实现接口,你覆盖基类的实现。我知道。但是实现类不必声明它们为公共的吗?对不起,如果这听起来有点迟钝,我经常在Java和C之间跳来跳去。在Java世界中,你不在接口上放置和访问修饰符,而在实现类上放置和访问修饰符hod(Java中没有属性)在隐式实现中-就像您的第一个示例一样-您需要将此属性标记为public。在显式实现中-否,您不能将它们标记为public,它们只能通过类型为
IMyInterface
public interface IMyInterface
...
    String MyProperty {get;}
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"; }
    }
}