One reason would be:
class Foo<out T>
{
T _store;
public T Get()
{
_store = default(T);
return _store;
}
}
This class contains a feature that is not covariant, because it has a field, and fields can be set to values. It is though used in a covariant way, because it is only ever assigned the default value and that is only ever going to be null
for any case where covariance is actually used.
As such it's not clear if we could allow it. Not allowing it would irritate users (it does after all match the same potential rules you suggest), but allowing it is difficult (the analysis has gotten slightly tricky already and we're not that even beginning to hunt for really tricky cases).
On the other hand, the analysis of this is much simpler:
void Main()
{
IFoo<object> foo = new Foo<string>();
Console.WriteLine(foo.Get());
}
interface IFoo<out T>
{
T Get();
}
class Foo<T> : IFoo<T>
{
T _store;
public T Get()
{
_store = default(T);
return _store;
}
}
It's easy to determine that none of the implementation of IFoo<T>
breaks the covariance, because it hasn't got any. All that's necessary is to make sure that there is no use of T
as a parameter (including that of a setter method) and it's done.
The fact that the potential restriction is a lot more arduous on a class than on an interface for similar reasons, also reduces the degree to which covariant classes would be useful. They certainly wouldn't be useless, but the balance of how useful they would be over how much work it would be to specify and implement the rules about what they would be allowed to do is much less than the balance of how useful covariant interfaces are over how over how much work it was to specify and implement them.
Certainly, the difference is enough that it's past the point of "well, if you're going to allow X it would be silly to not allow Y…".
The answer is always the same: because no one ever designed, specified, implemented, tested, documented and shipped that feature. All six of those things are necessary to make a feature happen. All of them cost huge amounts of time, effort and money. Features are not cheap, and we try very hard to make sure that we are only shipping those features which give the best possible benefits to our users given ...
– NarvaWhat would be required for C# to support X feature
, in which case the question is very much too broad and off-topic. – FivesWhy doesn't C# support variant generic classes?
, that answer does NOT directly impact develpers, it has NO impact. If you want a On Topic question, it would beIf c# does not support variant generic classes natively how can I emulate it
. – NarvaSome of us like to understand what makes things tick
I agree and do so myself, I have aspnetwebstack.codeplex.com memorized for that very reason. I'l state this again, the answer to your question in the title will most likely yeild a reason like, as I quoted Eric Lippert:In this particular case, the clear user benefit was in the past not large enough to justify the complications to the language which would ensue.
. That answer has no direct code benefit, it simply wasn't prioritized above other features. Instead ask how you can emulate the feature. – NarvaFoo<T>
has its own independent set of static members. If a reference to aMyClass<SiameseCat>
were cast to aMyClass<Animal>
, whose static members should it access? It might be possible for the CLR to support covariance for generic classes meeting some very strict criteria (e.g. no static members) but defining and testing for the necessary criteria would be a lot of work in and of itself. – Avar