Omar Kooheji
Omar Kooheji

Reputation: 55760

How do you override properties in C#?

I've got an interface say IMyInterface which is implemented by a class MyClass how do I declare properties with getters and setters that override rather than masking the ones in the interface?

For example for the interface:

public interface IMyInterface
{
    String MyProperty {get;}
}

If I do this I'm hiding the interface property

public class MyClass : IMyInterface
{
    public String MyProperty 
    { 
        get 
        {
             return "Whatever";
        }
    }
}

But if I do this I get an error saying that MyProperty can't be public:

public class MyClass : IMyInterface
{
    public String IMyInterface.MyProperty 
    { 
        get 
        {
             return "Whatever";
        }
    }
}

Upvotes: 2

Views: 209

Answers (6)

Matthias Meid
Matthias Meid

Reputation: 12513

As interfaces have no implementations, overriding is a concept that does not apply to interfaces. Therefore interface member don't need to be virtual.

You override when using class inheritance. You need to make them virtual in a base class, and use the override keyword in a subclass:

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

If you explicitly implement an interface, you need no public modifier since the member is only visible when consumer use the interface type:

class FooExplicit : IFoo
{
    // IFoo f = new FooExplicit(); <- Bar is visible
    // FooExplicit fe = new FooExplicit(); <- there is no Bar
    string IFoo.Bar { get; private set; }
}

As IFoo.Bar is still tied only to the interface it's still implicitly public. In Java you could add the public modifier if you like (optional of course). C# in contrast prohibits this.

Upvotes: 5

StuartLC
StuartLC

Reputation: 107247

Declaring a property in an interface doesn't actually provide an implementation of the property on the interface.

i.e. By stating

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

You are in fact just requiring that implementations of the interface must provide a property MyProperty which has a getter. I do agree however that the syntax can easily be confused with automatic properties, but in the case of the interface, there is no backing field.

Update

Explicit interface implementation is used to distinguish the case where the same property name is required for more than one interface. Possibly the following clarifies this?

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

Upvotes: 0

Habib
Habib

Reputation: 223247

Are they then implicitly public?

interface memebers are implicity public, you can use any access specifier with the interface members in the interface.

interface C# - MSDN

Interface members are automatically public, and they can't include any access modifiers.

For comment:

I'm talking about the implementing class where it complains about me using the public modifier on my declaration of IMyInterface.MyProperty

Since you are doing Explicit interface implementation, The method can only be called against an interface object, It can't be called against the class object. Since all members of interface are implicitly public it would be redundant and that is why not allowed.

See this article: Explicit interface implementation – to hide interface member in implementing type

To implement an interface explicitly, you drop the public access specifier (all interface members are public), and predicate the method name with the interface name and dot

Upvotes: 1

Jarek
Jarek

Reputation: 3379

What do you mean by hidding? Your first example is normal, implicit implementation of interface's property. You're not hidding it, you're implementing it.

Your second example is explicite interface implementation - it cannot be public by design. You will only be able to call it when your variable type will be of IMyInterface.

You can of course mark your property as virtual in implementing class to allow it to be overriden in iheritting classes, but that's another story.

Upvotes: 1

varun
varun

Reputation: 4650

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

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

Upvotes: 1

DevProve
DevProve

Reputation: 192

this may help 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;
}
}

Upvotes: 0

Related Questions