问题描述
我最近遇到麻烦,当尝试AddRange(IEnumerable)到一个列表。
我理解,期望List参数的方法不能满足列表,因为他们可能尝试添加
但是如果我得到这个正确,因为IEnumerables本身不能改变,它应该在这种情况下工作。
p>我认为代码看起来像这样:
class Foo
{
}
class Bar:Foo
{
}
class FooCol
{
private列表< Foo> m_Foos = new List< Foo> ();
public void AddRange1(IEnumerable< Foo> foos)
{
m_Foos.AddRange(foos); // does work
}
public void AddRange2< T>(IEnumerable< T> foos)其中T:Foo
{
m_Foos.AddRange(foos); //不工作
}
}
类程序
{
static void Main(string [] args)
{
FooCol fooCol = new FooCol();
List< Foo> foos = new List< Foo> ();
List< Bar> bars = new List< Bar> ();
fooCol.AddRange1(foos); // does work
fooCol.AddRange1(bars); //不工作
fooCol.AddRange2(foos); // does work
fooCol.AddRange2(bars); // does work
}
}
我尝试传递一个提示编译器在AddRange2方法,但这只是转移到问题。
我的思维方式有缺陷吗?这是对语言的限制还是由设计?
IIRC,对这种操作的支持被添加到Java 1.5,因此也许它将被添加到C#
$ p这是协方差,将在C#4.0 /中修复。 NET 4.0。现在,通用选项是最好的答案( IEnumerable< T>
- )。
但是在通用方法中,你必须考虑 T
。您也可以使用LINQ来使用 Cast< T>
或 OfType< T>
I recently run into trouble when trying to AddRange(IEnumerable) to a List. Probably a classic issue, but I do not really get it yet.
I understand that methods expecting a List parameter are not satisfied with a List, because they might try to add a Base to the List, which is obviously impossible.
But if i get this correctly, since IEnumerables themselves cannot be changed, it ought to work in this case.
The code i thought of looks like this:
class Foo
{
}
class Bar : Foo
{
}
class FooCol
{
private List<Foo> m_Foos = new List<Foo> ();
public void AddRange1(IEnumerable<Foo> foos)
{
m_Foos.AddRange (foos); // does work
}
public void AddRange2<T>(IEnumerable<T> foos) where T : Foo
{
m_Foos.AddRange (foos); // does not work
}
}
class Program
{
static void Main(string[] args)
{
FooCol fooCol = new FooCol ();
List<Foo> foos = new List<Foo> ();
List<Bar> bars = new List<Bar> ();
fooCol.AddRange1 (foos); // does work
fooCol.AddRange1 (bars); // does not work
fooCol.AddRange2 (foos); // does work
fooCol.AddRange2 (bars); // does work
}
}
I tried to pass a hint to the compiler in the AddRange2 method, but this just moved to problem around.
Is my way of thinking flawed? Is this a limitation of the language or is it by design?
IIRC, support for this kind of operations was added to Java 1.5, so maybe it will be added to C# at some point in the future, too...?
This is covariance, and will be fixed in C# 4.0 / .NET 4.0. For now, the generic option is the best answer (for IEnumerable<T>
- not IList<T>
etc).
But within the generic method, you have to think in terms of T
. You could also use Cast<T>
or OfType<T>
with LINQ to achieve something similar.
这篇关于C#无法从IEnumerable转换< Base>到IEnumerable< Derived>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!