0

I was just coding a simple C# interface, and I put a property in it without thinking it through too far. 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?

John Humphreys
  • 37,047
  • 37
  • 155
  • 255

3 Answers3

2

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. 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.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • Just to be clear, when you say "Those are properties, and those are allowed", you mean that the declaration is allowed, right? So this same syntax would declare properties in the interface, but not provide the backing data item. The class that implements the interface implements the properties and provides the backing data item. Please correct me if I'm still wrong :) Thank you! – John Humphreys Dec 12 '13 at 14:43
2

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. 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).

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).

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).

D Stanley
  • 149,601
  • 11
  • 178
  • 240
2

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; }
    }
Allan Elder
  • 4,052
  • 17
  • 19