Answer the question
In order to leave comments, you need to log in
Generic Types and Double UpCast?
Hello everyone, I have the following example:
public abstract class Shape { }
public class Circle : Shape { }
public interface IContainer<out T>
{
T Figure { get; }
}
public class Container<T> : IContainer<T>
{
private T figure;
public Container(T figure)
{
this.figure = figure;
}
public T Figure
{
get { return figure; }
}
}
class Program
{
static void Main()
{
Circle circle = new Circle();
IContainer<Shape> container = new Container<Circle>(circle);
Console.WriteLine(container.Figure.ToString());
// Delay.
Console.ReadKey();
}
}
IContainer<Shape> container = new Container<Circle>(circle);
IContainer<Shape> container = new Container<Shape>(circle);
Answer the question
In order to leave comments, you need to log in
You don't quite understand covariance in generic interfaces and you've got a lot of things mixed up.
First, the type of the figure field does not change to any other. It cannot change "on the fly", because. a concrete object of a concrete class has already been created.
The return type of the Figure property also does not change.
I repeat once again - the class and its instance do not change any types of either fields or properties.
For some reason, you perceive the cast of a class type to an interface as a conversion of the value of an object - as if another Circle will be created, which will have other types of fields. It is absolutely not true.
When it comes to reference types (and polymorphism using interfaces only works with such types), then you should clearly understand that you are working with a reference, and type casting for a reference cannot affect the object itself in any way. In other words, you simply change the "window" through which you look at the object.
So covariance in the case of interfaces is purely a matter of typing. When co- and contravariance was added to C#, in fact, you were allowed to consider that IContainer is a special case of IContainer, and if so, ANY IContainer can be treated as IContainer. In earlier versions of the language, this could not be done - only Container could be treated as IContainer.
If something is not clear in the answer, ask, because Your question sounds like you have a big gap in your understanding of the language somewhere. You dig into the details, making completely wrong assumptions about what is happening.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question