Reputation: 35
I define the following four classes:
class X
{
public X() {}
}
class A : IEnumerable<X>
{
public IEnumerator<X> GetEnumerator()
{
yield return new X();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
class Foo
{
public virtual IEnumerable<X> Values { get; set; }
}
class Bar : Foo
{
public override A Values { get; set; }
}
Foo is a class with a virtual property of type IEnumerable<X>
, and derived class Bar overrides this property with an instance of class A, which derives from IEnumerable<X>
. I expect return type covariance, but instead I encounter the error
'Bar.Values': type must be 'IEnumerable<X>' to match overriden member 'Foo.Values'
even though class A clearly implements IEnumerable<X>
.
What am I missing here? Why does the override type not work in this case?
Upvotes: 0
Views: 50
Reputation: 117144
Let's introduce a new typed called B
.
class B : IEnumerable<X>
{
public IEnumerator<X> GetEnumerator() { yield return new X(); }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
Now my implementation of Foo
could be like this:
class Foo
{
public virtual IEnumerable<X> Values { get; set; } = new B();
}
Perfectly legal.
Now let's implement a default Bar
, but with A
as the type of Values
.
class Bar : Foo
{
public override A Values
{
get => base.Values;
set => base.Values = value;
}
}
The get
is trying to return the value from base.Values
which is an instance of B
, not A
.
Bar
does not know what types Foo
might actually return so they return type must be the most general possible.
That's why this isn't allowed.
Upvotes: 3