Benison Sam
Benison Sam

Reputation: 2825

Enforce getter setter access at the interface level

I want to enforce access on getter or setter for a property at the interface level so that the same be followed in the class that implements it. I want to do something like below:

public interface IExample
{
    string Name
    {
        get;
        internal set;
    }
}

public class Example : IExample
{
    private string _name = String.Empty;
    string Name
    {
        get
        {
            return _name;
        }
        internal set
        {
            _name = value;
        }
    }
}

But unfortunately from what I know this is not allowed in C#. I think that is because interface are meant to only expose what that is with a public access(I haven't the slightest idea!).

What I need here is a way to implement this using any other coding pattern (preferably using interface) which will help me to enforce specific access on getter or setter of a property in all of its implemented classes.

I googled this and tried to go through MSDN docs for this but had no luck!

Upvotes: 4

Views: 1440

Answers (3)

Gabor
Gabor

Reputation: 3246

How about this? This can be a workaround:

// Assembly: A
public interface IExample
{
    string Name { get; }
}

// Assembly: B
using A;

public abstract class Example : IExample
{
    public string Name { get; protected internal set; }
}

public class SpecificExample : Example
{
    public void UpdateName(string name)
    {
        // Can be set because it has protected accessor
        Name = name;
    }
}

class Program
{
    static void Main(string[] args)
    {
        IExample e = new SpecificExample()
        {
            // Can be set because it has internal accessor
            Name = "OutsideAssemblyA"
        };
    }
}

// Assembly: C
using A;

public abstract class Example : IExample
{
    public string Name { get; protected internal set; }
}

public class AnotherSpecificExample : Example
{
    public void UpdateName(string name)
    {
        // Can be set because it has protected accessor
        Name = name;
    }
}

class Program
{
    static void Main(string[] args)
    {
        IExample e = new AnotherSpecificExample()
        {
            // Can be set because it has internal accessor
            Name = "OutsideAssemblyA"
        };
    }
}

This works but you have to create (or copy-paste) the abstract class Example in every assembly in which you would like to create a specific implementation of it, e.g. SpecificExample or AnotherSpecificExample.

Upvotes: 1

Ian Mercer
Ian Mercer

Reputation: 39277

Using internal on a setter is somewhat nasty anyway but if you really want to do it you could define a second interface that is itself internal AND make Example internal to your assembly.

public interface IExample
{
    string Name
    {
        get;
    }
}

internal interface IExampleInternal
{
    string Name
    {
        set; get;
    }
}

internal class Example : IExample, IExampleInternal
{
    public string Name { get; set; } = string.Empty;
}

Now anything in the same assembly can take an IExampleInternal and outside only ever gets to see IExample. You do however have to list both interfaces on every class you create.

Upvotes: 1

Olivier Citeau
Olivier Citeau

Reputation: 169

this is not possible. As everybody told you, interfaces are meant to define public access. How about the following code ?

public interface IExample
{
    string Name
    {
        get;
    }
}

Upvotes: 0

Related Questions