Add 'set' to properties of interface in C#

11,311

Solution 1

I don't see any reason why what you have posted shouldn't work? Just did a quick test and it compiles alright, but gives a warning about hiding. This can be fixed by adding the new keyword, like this:

public interface IMutableUser : IUser
{
    new string Username { get; set; }
}

An alternative would be to add explicit set methods; eg:

public interface IMutableUser : IUser
{
    void SetUsername(string value);
}

Of course, I'd prefer to use setters, but if it's not possible, I guess you do what you have to.

Solution 2

You could use an abstract class:

interface IUser
{
    string UserName
    {
        get;
    }
}

abstract class MutableUser : IUser
{
    public virtual string UserName
    {
        get;
        set;
    }
}

Another possibility is to have this:

interface IUser
{
    string UserName
    {
        get;
    }
}

interface IMutableUser
{
    string UserName
    {
        get;
        set;
    }
}

class User : IUser, IMutableUser
{
    public string UserName { get; set; }
}

Solution 3

You can "override" properties in an interface by explicitly implementing the interfaces. Chris' answer is likely all you'll need for the scenario you've outlined, but consider a slightly more complex scenario, where you need a getter/setter on your class, but the interface only defines the getter. You can get around this by doing the following:

public class MyUser : IUser
{

    IUser.MyProperty { get { return "something"; } }

    public MyProperty { get; set; }

}

By explicitly implementing IUser.MyProperty, you satisfy the contract. However, by providing public MyProperty, the API for your object will never show the explicit interface version, and will always use MyProperty with the get/set.

Share:
11,311
strager
Author by

strager

Live code reviews and help: https://twitch.tv/strager

Updated on June 06, 2022

Comments

  • strager
    strager about 2 years

    I am looking to 'extending' an interface by providing set accessors to properties in that interface. The interface looks something like this:

    interface IUser
    {
        string UserName
        {
            get;
        }
    }
    

    I want something like this:

    interface IMutableUser : IUser
    {
        string UserName
        {
            get;
            set;
        }
    }
    

    I need the inheritence. I cannot copy the body of IUser into IMutableUser and add the set accessors.

    Is this possible in C#? If so, how can it be accomplished?

  • strager
    strager over 15 years
    I need MutableUser to inherit IUser. I will look into the first method.
  • strager
    strager over 15 years
    Using an abstract class works. However, it doesn't seem to be the most elegent solution here. Will leave this question open for a bit for possible "better" answers.
  • strager
    strager over 15 years
    Adding new worked great! Thanks! Can you update your answer with an example (for others)?
  • TestyTest
    TestyTest over 15 years
    From practical viewpoint: interfaces evolve very badly over time. All implementers of the interface will break with every change to this contract....
  • Nicolas Fall
    Nicolas Fall over 12 years
    @PatrickPeters - I assume that comment was directed at the SetUserName method? I don't see issues with the first option. Some of the possible breaks are eliminated if the implementer follows explicit implementation where appropriate.
  • TestyTest
    TestyTest over 12 years
    @Maslow: no not specifically, my commment was more in generic way. MS has specific guidelines when to use an interface. See msdn.microsoft.com/en-us/library/ms229013.aspx