I have a class Foo
and a static class FooFactory
, which is used to create instances of Foo
and Foo
derived classes via the following API:
public static class FooFactory {
public static T Create<T>() where T : Foo, new() {
...
return new T();
}
}
The new()
specialization of the T
type parameter requires Foo
to have a public
default constructor. In other words, nothing is preventing a user of Foo
to initialize the class directly via the constructor.
However,
FooFactory
is intended to keep track of allFoo
instances, so I want to enforce the user to create allFoo
andFoo
derived instances via theFooFactory
.
The closest I have been able to prevent direct constructor initialization is to decorate the Foo
default constructor with the [Obsolete("message", error: true)]
attribute:
public class Foo {
[Obsolete("Fail", true)]
public Foo() { ... }
}
With this decoration the code does not compile when I call the Foo
default constructor directly, whereas initialization via FooFactory.Create<Foo>()
works.
But with this [Obsolete]
decoration, I still have problems with derived classes. The following won't even compile due to the error: true
setting for the Foo
default constructor:
public class Bar : Foo { ... }
public class Baz : Foo { public Baz() : base() { ... } }
I can declare a protected
Foo
constructor overload that the derived classes invoke instead of the default constructor, but then I will have no ability to programmatically prevent direct initialization of the derived classes.
If I set error
in the ObsoleteAttribute
to false
, I get compilation warnings instead, but I would like to have stronger discouragement than warnings...
Is there any way that I can programmatically prevent direct invocation of the default constructor for both Foo
and derived classes when the default constructors are required to be declared public
?