Здесь утонченная версия классов, которые у меня есть.
public abstract class BaseParent { }
public abstract class ChildCollectionItem<T>
where T : BaseParent
{
// References a third-party object that acts as the parent to both the collection
// items and the collection itself.
public T parent;
// References the collection to which this item belongs. The owning collection
// will share the same parent type. The second type argument indicates what
// type of items the collection will store.
public ChildCollection<T, ChildCollectionItem<T>> owningCollection;
}
public abstract class ChildCollection<T, U> : CollectionBase
where T : BaseParent
where U : ChildCollectionItem<T>
{
// References a third-party object that acts as the parent to both the collection
// items and the collection itself.
public T parent;
// Adds an item of type 'U' to the collection. When added, I want to set the
// owningCollection value of the item to 'this' collection.
public int Add(U item)
{
int indexAdded = this.List.Add(item);
// THIS LINE IS THROWING A COMPILE ERROR - Cannot convert type
// 'ChildCollection<T, U>' to 'ChildCollection<T, ChildCollectionItem<T>>'
item.owningCollection = this;
return indexAdded;
}
Я понимаю, что эта проблема, вероятно, связана с тем, что класс ChildCollection не знает ограничений типа, установленных в ChildCollectionItem, потому что, если бы это было, здесь не было бы проблем. Тип 'U' всегда должен быть элементом ChildCollectionItem, где ChildCollectionItem 'T' всегда совпадает с ChildCollection 'T'.
Мне нужно знать, есть ли способ, которым я могу использовать 'this', чтобы он компилировал или изменял мои классы/ограничения, чтобы компилятор мог справиться с этим без приведения.
Проблема заключается в дисперсии - U может быть другим типом, кроме как только ChildCollectionItem<T>
- это может быть тип, полученный из ChildCollectionItem<T>
, а Foo<DerivedClass>
несовместим с Foo<BaseClass>
.
Как насчет введения другого базового класса в ChildCollection<T, U>
?
using System.Collections;
public abstract class BaseParent { }
public abstract class ChildCollectionItem<T>
where T : BaseParent
{
public T parent;
public ChildCollection<T> owningCollection;
}
public abstract class ChildCollection<T> : CollectionBase
where T : BaseParent
{
}
public abstract class ChildCollection<T, U> : ChildCollection<T>
where T : BaseParent
where U : ChildCollectionItem<T>
{
public T parent;
public int Add(U item)
{
int indexAdded = this.List.Add(item);
item.owningCollection = this;
return indexAdded;
}
}
эта проблема, вероятно, к тому, что ChildCollection класс не знает тип ограничений, установленных в ChildCollectionItem, потому что если бы это было здесь не должно быть проблем.
Вышеприведенное утверждение неверно.
Тип 'U' всегда должен быть ChildCollectionItem, где ChildCollectionItem 'T' всегда является то же, что и ChildCollection 'T'.
Как вы это понимаете? U гарантируется через его ограничение, чтобы быть конвертируемым посредством эталонного преобразования в этот тип. Не гарантируется такой тип, который требуется. U может быть любым типом, полученным из этого типа.
Если U всегда является типом, то почему именно "U" в первую очередь? Почему бы не просто полностью исключить параметр типа и заменить все его использование тем типом, который вы ожидаете?
Ваше ограничение на U очень специфично; U должен иметь тип ChildCollectionItem. Можно ли в вашем приложении определить коллекцию как
public abstract class ChildCollection<T, ChildCollectionItem<T>>
Это избавит вас от необходимости бросать.