I want to allow inheritance, but forbid the direct construction of any of the inherited classes. Instead, I want to force the usage of the custom method New().
The goal is to make sure that every instance of inherited classes is a transparent proxy of itself.
In this case, it's not possible to make the constructor private or internal. Otherwise, you can't inherit from the class anymore outside of the assembly.
Is there any elegant way to solve that? My current solution:
public abstract class Class<This> : MarshalByRefObject where This : Class<This>
{
private static bool ShouldThrowOnConstruction = true;
private static readonly object Lock = new object();
public static This New()
{
lock (Lock)
{
ShouldThrowOnConstruction = false;
var instance = (This)new ClassProxy<This>().GetTransparentProxy();
ShouldThrowOnConstruction = true;
}
return instance;
}
protected Class()
{
if (ShouldThrowOnConstruction)
{
throw new InvalidOperationException("Direct use of the constructor is forbidden. Use New() instead.");
}
}
}
Why not use a static factory function instead of a constructor?
e.g.
That's extremely difficult to misuse, and doesn't have the same race condition problems that you required the thread locking for.
I suppose this means that all subclasses would also need to make their default constructor private. Is that outside your control?
Edit:
In the case you want to guarantee it can't be called, make the constructor throw an exception
throw new InvalidOperationException("Direct use of the constructor is forbidden. Use Build() instead.");, and yourGetTransparentProxymethod shouldn't callnewto construct the object but instead useFormatterServices.GetUninitializedObject()to bypass the constructor. That should allow the instance to be created, but it has a bit of a code smell.Something like this: