2

我有 2 个课程: ParentChild:Parent.

当我下一步做:

IMyRepository<Child> _childRepository=new MyRepository<Child>();
IMyRepository<Parent> _repository=childRepository;

我收到错误“Сan't convert source type to target type”。请告诉我为什么这段代码不起作用。

4

5 回答 5

5

因为,那么您将能够插入 a new AnotherDifferentChild()– 这不可能存在于 a 中IList<Child>。如果您想了解有关详细信息的更多信息,请查找有关CovarianceConvarianceInvariance的文章。

如果你想创建一个新的列表,持有 type 的引用Parent,你可以使用Cast<T>()LINQ 中的方法:

IList<Parent> parentList = childList.Cast<Parent>().ToList();
于 2013-09-18T09:19:41.037 回答
1

我对强制转换不太了解,但我认为泛型不会对父类型进行隐式强制转换。

但添加

childRepository.Cast<Parent>()

应该使它成为可能,尽管您可能必须为此进行扩展,IEnumerable<T>这将创建一个新的IMyRepository<T>

于 2013-09-18T09:20:37.790 回答
1

试试这个

List<Parent> listOfParent = new List<Child>().Cast<Parent>().ToList();

或者

List<Parent> listOfParent = new List<Child>().ConvertAll(x => (Parent)x);
于 2013-09-18T09:22:10.977 回答
1

如果我们使用稍微不同的类名,那么不允许您这样做的原因就会变得很清楚。

考虑这个类层次结构:

public class Mammal
{
}

public class Cat: Mammal
{
    public void Meow(){}
}

现在假设您有以下列表:

IList<Cat> cats = new List<Cat>{ new Cat() }

cats[0].Meow(); // All is fine.

现在让我们假设您可以分配catsIList<Mammal>

IList<Mammal> mammals = cats; // Not allowed, but pretend it is.

mammals.Add(new Mammal()); 

// Because 'mammals' is referencing 'cats', then adding an element to 'mammals'
// will affect 'cats' too - they are both the same list.
// So now cats has two elements; the first is a Cat and the second is a Mammal.

// So now what happens when we do this?

cats[1].Meow(); // Ask a Mammal to Meow(). Ooopsie!
于 2013-09-18T09:35:19.033 回答
0

想象一下,如果你能做这样的事情会发生什么。您可以编写如下代码:

    IList<Child> children = new List<Child>();
    IList<Parent> parents = children;
    parents.Add(new Parent());

请注意,parents它仍然是对与 相同的对象的引用children,但是我们设法添加了一个不是 ! 的实例的Child对象IList<Child>

正如另一个答案所提到的,这完全与协方差问题有关(与称为范畴论的数学领域密切相关——如果你有机会看到它会很有趣)。

本质上,如果我们写T-> S, 对于S多态到T的两种类型,例如Parent -> Child,那么如果泛型保持这种关系,它就是协变的。例如IEnumerable是一个协变,因为IEnumerable<Object> -> IEnumerable<String>. 编译器知道这一点,因为您可以将 an 强制IEnumerable<String>转换为IEnumerable<Object>.

于 2013-09-18T09:35:29.873 回答