来自 IEnumerable 的 foreach 中特定类型的对象 [英] Objects of a specific type in foreach from an IEnumerable
问题描述
我正在使用仅实现非通用 IEnumerable
和 ICollection
的遗留集合对象.当我尝试将这个对象与 foreach
一起使用时,这个对象究竟会发生什么,在 foreach 表达式的 LHS 上给出更具体的类型?
I'm working with a legacy collection object that only implements non-generic IEnumerable
and ICollection
. What exactly happens with this object when I try to use this object with a foreach
giving a more specific type on the LHS of the foreach expression?
// LegacyFooCollection implements non-generic IEnumerable
LegacyFooCollection collection = GetFooCollection();
foreach (Foo f in collection)
{
// etc.
}
我知道(因为我已经尝试过了)当 collection
中的所有内容都属于 Foo
类型时,这是安全的,但如果失败会怎样?>
I know (because I've tried it) that this is safe when everything in collection
really is of type Foo
, but what happens if that fails?
推荐答案
C# 编译器会为您隐式执行强制转换.在转换方面(但仅在这些方面1)它相当于:
The C# compiler performs the cast implicitly for you. In terms of the casting (but only in those terms1) it's equivalent to:
foreach (object tmp in collection)
{
Foo f = (Foo) tmp;
...
}
请注意,泛型集合也会发生这种情况:
Note that this will happen with generic collections too:
List<object> list = new List<object> { "hello", "there", 12345 };
// This will go bang on the last element
foreach (string x in list)
{
}
这在 C# 4 规范的第 8.8.4 节中有详细说明.
This is all detailed in section 8.8.4 of the C# 4 spec.
如果您使用 .NET 3.5 或更高版本并且只想选择适当类型的项目,则可以使用 Enumerable.OfType
:
If you're using .NET 3.5 or higher and you want to only select items of the appropriate type, you can use Enumerable.OfType
:
LegacyFooCollection collection = GetFooCollection();
foreach (Foo f in collection.OfType<Foo>())
{
// etc.
}
这对于 LegacyFooCollection
可能不是必需的,但是当您尝试在表单中查找(例如)所有 TextBox
控件时,它会很有用.
That may not be necessary for a LegacyFooCollection
, but it can be useful when you're trying to find (say) all the TextBox
controls in a form.
1 区别在于:
- 在你的原始代码中,
f
是只读的;在转换"中它是可写的 - 在您的原始代码中,如果您捕获
f
,您(当前)将在所有迭代中捕获单个变量,而不是在转换"中每次迭代捕获一个单独的变量
- In your original code,
f
is read-only; in the "conversion" it's writable - In your original code, if you capture
f
you will (currently) capture a single variable across all iterations, as opposed to a separate variable per iteration in the "conversion"
这篇关于来自 IEnumerable 的 foreach 中特定类型的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!