3

The following code is a valid C# construct that compile juste fine.

public class Weird : Weird.IWeird
{
    private interface IWeird
    {
    }
}

What would be the possible uses of this?

Edit: This question is more specific that this one: "What is a private interface?". It shows that it's possible to implement a private interface from the parent type itself, which seems to be rather pointless. The only use I can think of would be a weird case of interface segregation where you would want to pass an instance of the parent class to a nested class instance as IWeird.

Community
  • 1
  • 1
Romain Verdier
  • 12,833
  • 7
  • 57
  • 77

1 Answers1

3

This is probably one of these situations in compiler development when prohibiting something has a higher cost than allowing it. Prohibiting this use would require writing and maintaining code to detect this situation, and report an error; if the feature works as-is, this is an additional work for the team, and it could be avoided. After all, perhaps someone with good imagination could figure out a way to use the feature.

As far as a useful example goes, one potential use is to make another implementation in the class, and use it as an alternative without exposing it to the users of the API:

public class Demo : Demo.Impl {
    // Private interface
    private interface Impl {
        public bool IsValidState {get;}
        void DoIt();
    }
    // Implementation for the error state
    private class Error : Impl {
        public bool IsValidState { get { return false; } }
        public void DoIt() {
            Console.WriteLine("Invalid state.");
        }
    }
    private readonly string name;
    // Implementation for the non-error state
    public bool IsValidState { get { return true; } }
    public void DoIt() {
        Console.WriteLine("Hello, {0}", name);
    }
    // Constructor assigns impl depending on the parameter passed to it
    private readonly Impl impl;
    // Users are expected to use this method and property:
    public bool IsValid {
        get {
            return impl.IsValidState;
        }
    }
    public void SayHello() {
        impl.DoIt();
    }
    // Constructor decides which impl to use
    public Demo(string s) {
        if (s == null) {
            impl = new Error();
        } else {
            impl = this;
            name = s;
        }
    }
}

As far as best practices go, this design is questionable at best. In particular, I would create a second nested class for the non-error implementation, rather than reusing the main class for that purpose. However, there is nothing terribly wrong with this design (apart from the fact that both IsValidState and DoIt are visible) so it was OK of the C# team to allow this use.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523