Internal property setters in C#

larryq picture larryq · Nov 28, 2012 · Viewed 12.5k times · Source

I'm trying to figure out a good way to approach this. I have a Customer class which implements the ICustomer interface. This interface has a number of properties in it:

public interface ICustomer
{

   string FirstName {get; set;}
   string LastName  {get; set;}
}

I only want certain classes to have the ability to set those properties however; namely, those classes in the project. So I thought about making the setter internal:

public class Customer : ICustomer
{

   string FirstName {get; internal set;}
   string LastName  {get; internal set;}
}

I'd like to mark that setter as internal in the interface however, so there's no chance someone implements ICustomer and someone outside the assembly modifies those properties. Is there a good way to do this?

Answer

Servy picture Servy · Nov 28, 2012

The properties in the interface should be read only. It's acceptable for the concrete class that implements the interface to have a setter even if none is defined in the interface.

public interface ICustomer
{
   string FirstName { get; }
   string LastName  { get; }
}

public class Customer : ICustomer
{
   public string FirstName { get; internal set; }
   public string LastName  { get; internal set; }
}

If it's really important that the setter be exposed through an interface, rather than having the interface being entirely read-only, you can use something like this:

public interface IReadCustomer
{
    string FirstName { get; }
    string LastName { get; }
}

internal interface IWriteCustomer
{
    string FirstName { set; }
    string LastName { set; }
}

internal interface IReadWriteCustomer : IReadCustomer, IWriteCustomer
{ }

public class Customer : IReadWriteCustomer
{
    private string _firstName;
    private string _lastName;

    public string FirstName
    {
        get { return _firstName; }
        internal set { _firstName = value; }
    }
    public string LastName
    {
        get { return _lastName; }
        internal set { _lastName = value; }
    }

    string IReadCustomer.FirstName
    {
        get { return FirstName; }
    }

    string IReadCustomer.LastName
    {
        get { return LastName; }
    }

    string IWriteCustomer.FirstName
    {
        set { FirstName = value; }
    }

    string IWriteCustomer.LastName
    {
        set { LastName = value; }
    }
}