всем привет, имеется следующий пример:
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);
-экземпляр circle (передаваемый в качестве аргумента конструктора) ни приводится ни к какому типу в данном случае - т.к тип Т (я знаю, что правильно говорить тип места заполнения типом Т, но просто "тип Т" - будет короче) у класса Container мы закрыли тем же типом, что и данный экземпляр (и я имею ввиду, что т.к типы у них одинаковые, то и приводится не к чему.)
Итак, у нас сперва тип Container приводим к типу IContainer, а поле figure типа Circle приводится к типу Shape.
Почему поле figure внутри класса Container приводится к типу Shape?
итак мои предположения:
1) передаваемый в качестве аргумента экземпляр тут ни причем - т.к как уже было сказанно выше сам экземпляр никчему не приводится.
2)Из-за того, что тип Container мы привели к типу IContainer - тип Т у которого мы закрыли типом Shape
- и отсюда возникает еще один вопрос: у нас одновременно происходит как бы два UpCast -а : Container - IContainer;
Circle-Shape; - какой из них так скажем влияем на передаваемый аргумент конструктора - наш экземпляр circle (да-да, я знаю, что выше писал, что UpCast -a экземпляра circle не происходит - просто в предыдущем примере экземпляр приводится к типу Shape )
IContainer<Shape> container = new Container<Shape>(circle);
- но, раз поле figure меняет тип, а ссылка на это поле хранится в этом экземпляре, который мы передаем в качестве аргумента конструктора.
Моя догадка заключается в том, что раз мы тип Т у Container (Circle) - тот тип которого и аргумент конструктора circle - приводим к типу Т у IContainer(Shape), то и этот аргумент конструктора типа Circle также неявно UpCast - ится "следуя" изменениям своего типа - и соответственно затем произойдет UpCast типов внутри этого экземпляра в том числе и поля figure - которое изменит свой тип Circle на Shape.