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

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.


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

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