What's the difference between a public constructor in an internal class and an internal constructor?

前端 未结 5 1608
礼貌的吻别
礼貌的吻别 2020-12-03 04:16

I have an internal class, an internal constructor won\'t allow it to be used in a generic collection so I changed it to public. What\'s the accessibility if you have a publi

相关标签:
5条回答
  • 2020-12-03 04:48

    A public class with an internal constructor can still be used by outside code, if you return an object of that class from a public function.

    Outside code then has access to that object, but still can not create a new one.

    Assembly 1:
    
    public class Exclusive
    {
      internal Exclusive() {}
      public void DoSomething() {}
    }
    
    public class Factory
    {
      public Exclusive GetExclusive() { return new Exclusive(); }
    }
    
    Assembly 2:
    
    Factory MyFactory = new Factory();
    Exclusive MyExclusive = MyFactory.GetExclusive(); // Object is created in Assembly 1
    MyExclusive.DoSomething();
    
    Exclusive MyExclusive = new Exclusive(); // Error: constructor is internal
    

    Whereas an internal class can not be used outside the assembly at all:

    Assembly 1:
    
    internal class Exclusive
    {
      public Exclusive() {}
      public void DoSomething() {}
    }
    
    public class Factory
    {
      public Exclusive GetExclusive() { return new Exclusive(); }
    }
    
    Assembly 2:
    
    Factory MyFactory = new Factory();
    Exclusive MyExclusive = MyFactory.GetExclusive(); // Error: class Exclusive not found
    
    0 讨论(0)
  • 2020-12-03 04:49

    Having an internal or public constructor to an internal type would be equivalent in terms of visibility.

    0 讨论(0)
  • 2020-12-03 04:52

    The two are essentially the same. One argument I've seen for distinguishing between them is that making your constructor internal ensures the type will only ever be instantiated by types within the current assembly, even if it is later decided that the type itself should be public instead of internal. In other words you could decide to change the type's visibility without lifting restrictions on its instantiation.

    Making the constructor public has the opposite effect (obviously), and might be sensible if you want for it to be possible to instantiate the type anywhere it is visible.

    Also, as you've already pointed out, one small difference is that if the constructor's internal, the type cannot be used as a generic type argument for a generic type with a where T : new() constraint, as this constraint requires for the constructor to be public.

    0 讨论(0)
  • 2020-12-03 04:53

    internal constructor are good when you don't want the client to create the instance. You'd usually want to do it if you want to control how the instance should be created.You will have to provide either a Factory to generate the class in another class within the same assembly to generate the instance internally and then expose as a property.

    0 讨论(0)
  • 2020-12-03 05:04

    Another important distinction is that to access an internal constructor using reflection, you need to specify binding flags in your call to Type.GetConstructor() - the Type.GetConstructor(Type[]) overload will only return a public constructor:

    using System;
    internal class WithPublic
    {
        public WithPublic() { }
    }
    
    internal class WithInternal
    {
        internal WithInternal() { }
    }
    
    public class Program
    {
        public static void Main()
        {
            Console.WriteLine(typeof(WithPublic).GetConstructor(new Type[] { }) == null); //false
            Console.WriteLine(typeof(WithInternal).GetConstructor(new Type[] { }) == null); //true
        }
    }
    

    This might be important when you're using a library which utilizes the Type.GetConstructor(Type[]) overload, like Microsoft Unity.

    0 讨论(0)
提交回复
热议问题