连接通用类的转换问题

时间:2009-10-21 15:11:09

标签: c# .net generics casting

这是我所拥有的课程的简化版本。

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'转换为编译,或修改我的类/约束,以便编译器可以在没有强制转换的情况下处理它。

3 个答案:

答案 0 :(得分:4)

问题是方差之一 - 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;
  }
}

答案 1 :(得分:4)

  

这个问题可能是由于   到了ChildCollection的事实   class不知道类型   设定的约束   ChildCollectionItem,因为如果是的话   这里不应该有问题。

上述说法不正确。

  

类型'U'应始终为a   ChildCollectionItem在哪里   ChildCollectionItem'T'始终是   与ChildCollection'T'相同。

你怎么想的? U通过其约束保证可通过引用转换转换为该类型。不保证 该类型,这是必需的。 U可以是从该类型派生的任何类型。

如果U总是那种类型,那么为什么首先出现“U”?为什么不完全消除类型参数并用它期望的类型替换它的每一种用法?

答案 2 :(得分:0)

你对U的约束是非常具体的; U必须是ChildCollectionItem类型。您的应用程序是否可以将集合定义为

public abstract class ChildCollection<T, ChildCollectionItem<T>>

这样就不需要施放。