Visibility of nested class constructor

后端 未结 6 1057
渐次进展
渐次进展 2021-02-13 18:41

Is there a way to limit the instantiation of the nested class in C#? I want to prevent nested class being instantiated from any other class except the nesting class, but to allo

6条回答
  •  半阙折子戏
    2021-02-13 19:28

    If you need to meet one of the following requirements:

    • You want the nested class to be sealed,
    • You don't want to copy all the nested class's method signatures to an interface like in Lee's answer,

    I found a solution similar to the one posted by ak99372, but without using a static initializer:

    public class Outer
    {
        private interface IPrivateFactory
        {
            T CreateInstance();
        }
    
        public sealed class Nested
        {
            private Nested() {
                // private constructor, accessible only to the class Factory.
            }
    
            public class Factory : IPrivateFactory
            {
                Nested IPrivateFactory.CreateInstance() { return new Nested(); }
            }
        }
    
        public Nested GetNested() {
            // We couldn't write these lines outside of the `Outer` class.
            IPrivateFactory factory = new Nested.Factory();
            return factory.CreateInstance();
        }
    }
    

    The idea is that the Nested class's constructor is accessible only to the Factory class, which is nested one level deeper. The Factory class explicitly implements the method CreateInstance from the private interface IPrivateFactory, so that only those who can see IPrivateFactory can call CreateInstance and get a new instance of Nested.

    Code outside the Outer class can't freely create instances of Nested without asking Outer.GetNested(), because

    1. Outer.Nested's constructor is privated, so they can't call it directly
    2. Outer.Nested.Factory can be instantiated, but can't be cast to IPrivateFactory, so its CreateInstance() method can't be called.

    Note that I wouldn't recommend using that pattern heavily in production code, but it's a trick I find useful to have up my sleeve on rare occasions.

提交回复
热议问题