Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
We can specify a
"derived from"
constraint on generic type parameters like this:
class Bar<T> where T : IFooGenerator
Is there a way to specify NOT derived from?
My use-case: I have a bunch of FooGenerator
s that are parallelizable, with the same parallelization code for each, but we don't want them to always be parallelized.
public class FooGenerator : IFooGenerator
public Foo GenerateFoo() { ... }
Thus, I create a generic container class for generating Foo in parallel:
public class ParallelFooGenerator<T> : IFooGenerator where T : IFooGenerator
public Foo GenerateFoo()
//Call T.GenerateFoo() a bunch in parallel
Since I want FooGenerator
and ParallelFooGenerator<FooGenerator>
to be interchangeable, I make ParallelFooGenerator : IFooGenerator
. However, I clearly don't want ParallelFooGenerator<ParallelFooGenerator>
to be legal.
So, as an auxiliary question, is there perhaps a better way to design this if "not derived from" constraints are impossible?
–
–
–
interface ISerialFooGenerator : IFooGenerator { }
interface IParallelFooGenerator : IFooGenerator { }
public class FooGenerator : ISerialFooGenerator
public Foo GenerateFoo()
//TODO
return null;
public class ParallelFooGenerator<T> : IParallelFooGenerator
where T : ISerialFooGenerator, new()
public Foo GenerateFoo()
//TODO
return null;
–
–
ParallelFooGenerator<ParallelFooGenerator>
already isn't possible, because ParallelFooGenerator
is a generic type and you didn't specify a generic argument.
For example, ParallelFooGenerator<ParallelFooGenerator<SomeFooGenerator>>
is possible -- and would allowing such a type really be that bad?
The long answer (still no):
Microsoft puts it well in their explanation of type constrains: "The compiler must have some guarantee that the operator or method it needs to call will be supported by any type argument that might be specified by client code."
The fundamental purpose of constraints is not to prohibit certain types from being used, but rather to allow the compiler to know what operators or methods are supported. You can, however, check if a type implements/inherits a specific interface/base class at run-time and throw an exception. With that, though, you will not be able to get a design-time error from intellisense.
I hope this helps.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.