简体   繁体   English

接口和抽象类中的C#属性

[英]C# Properties in interfaces & abstract classes

I was just coding a simple C# interface, and I put a property in it without thinking it through too far. 我只是在编写一个简单的C#接口,并在其中放置了一个属性,而没有考虑太多。 For example: 例如:

public interface IMyInterface
{
    string Name { get; set; }
    object[][] Data { get; set; 
}

I realized that I'm a little confused with properties when applied to interfaces and abstract base classes. 我意识到当应用于接口和抽象基类时,我对属性有些困惑。 In a normal class, this syntax would generate the accessor and mutator for a hidden string member that it generated behind the scenes. 在普通类中,此语法将为其在后台生成的隐藏字符串成员生成访问器和变异器。

Interfaces shouldn't be able to have data members. 接口不应具有数据成员。 So, does this syntax do something different in that case? 那么,在这种情况下,此语法是否有所不同?

What about for abstract classes? 那抽象类呢? If I put this same syntax in the abstract base and the derived class, would both end up with a hidden member? 如果我在抽象基类和派生类中使用相同的语法,那么两者最终都将是隐藏成员吗?

Interfaces shouldn't be able to have data members. 接口不应具有数据成员。

Those are properties, and those are allowed : 这些是属性,并且 允许

An interface contains only the signatures of methods, properties, events or indexers. 接口仅包含方法,属性,事件或索引器的签名。

See also c# properties on Interface . 另请参见接口上的c#属性 As for your second question: 至于第二个问题:

If I put this same syntax in the abstract base and the derived class, would both end up with a hidden member? 如果我在抽象基类和派生类中使用相同的语法,那么两者最终都将是隐藏成员吗?

Yes. 是。 You can prevent that by marking the property virtual on the base class and override on the derived class. 您可以通过在基类上将属性标记为virtual并在派生类上override来防止这种情况。

Interfaces shouldn't be able to have data members. 接口不应具有数据成员。 So, does this syntax do something different in that case? 那么,在这种情况下,此语法是否有所不同?

Technically it's not a data member - it's a get/set method pair that has an underlying data member. 从技术上讲,它不是数据成员-它是具有基础数据成员的get / set方法对。 There's no implementation. 没有实现。

What about for abstract classes? 那抽象类呢? If I put this same syntax in the abstract base and the derived class, would both end up with a hidden member? 如果我在抽象基类和派生类中使用相同的语法,那么两者最终都将是隐藏成员吗?

If the class is abstract and the property is virtual then yes, you will be overriding an auto-implemented property with another auto-implemented property (which is pointless). 如果该类是抽象的,并且该属性是virtual则是,您将用另一个自动实现的属性(没有意义)覆盖一个自动实现的属性。

If the class is abstract and the property is NOT virtual then you still have two implementations, but the base class is hiding the parent implementation rather than overriding it (which is still pointless if they're both auto-implemented). 如果类是抽象的,并且该属性不是virtual则您仍然有两个实现,但是基类将隐藏父实现而不是覆盖它(如果它们都是自动实现的,那仍然没有意义)。

If the property is abstract then the abstract class won't have an implementation. 如果属性是抽象的,则抽象类不会一个实现。 You'll have to implement the get/set in your concrete class (which could be auto-implemented bot doesn't have to be). 必须实现你的具体类了get / set( 可能是自动实现的机器人不必须的)。

The property declaration in the interface is completely separate from the implementation. 接口中的属性声明与实现完全分开。 Thus you can implement it using automatic properties 因此,您可以使用自动属性来实现它

    private class MyImpl : IMyInterface
    {
        public string Name { get; set; }
        public object[][] Data { get; set; }
    }

or declare your own backing field 或声明自己的支持字段

    private class MyImplBacked : IMyInterface
    {
        private string _name;

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public object[][] Data { get; set; }
    }

Same scenario in abstract classes 抽象类中的相同场景

    public abstract class MyAbstractClass
    {
        public abstract string Name { get; set; }
        public abstract object[][] Data { get; set; }
    }

    private class MyImpl : MyAbstractClass
    {
        public override string Name { get; set; }
        public override object[][] Data { get; set; }
    }

    private class MyImplBacked : MyAbstractClass
    {
        private string _name;

        public override string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public override object[][] Data { get; set; }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM