4

ListBoxコントロールには、ListItemCollectionItemsタイプのプロパティがあります。

なぜ書けないのか理解できます

foreach (var item in ShipperListBox.Items)
{
    if (item.Selected) count++;
}

しかし、代わりに書く必要があります

foreach (ListItem item in ShipperListBox.Items)
{
    if (item.Selected) count++;
}

それはListItemCollection実装IEnumerableと関係があり、そうではありません(この質問IEnumerable<ListItem>で説明されているように)。

しかし、私が得られないのは、次のことが問題にならない理由です。

for (int i = 0; i < ListBox1.Items.Count; i++)
{
    if (ListBox1.Items[i].Selected) count++;
}

ListItemCollectionのどの部分ListBox.Items[i]が、タイプがコンパイラーに明確になっていListItemますか?

4

3 に答える 3

1

を返すインデクサーListItemCollectionを実装しているためです。ListItem

これはとは別ですIEnumerable

于 2012-10-24T20:21:11.017 に答える
0

これはその一部であり、次の目的.OfType<ListItem>().Cast<ListItem>()明示的に存在します。

Cast(IEnumerable)メソッドを使用すると、必要な型情報を指定することにより、非汎用コレクションで標準のクエリ演算子を呼び出すことができます。たとえば、ArrayListはIEnumerableを実装していませんが、ArrayListオブジェクトでCast(IEnumerable)を呼び出すことにより、標準のクエリ演算子を使用してシーケンスをクエリできます。(ソース)

だからあなたは書くことができます

foreach (var item in ShipperListBox.Items.OfType<ListItem>())
{
    if (item.Selected) count++;
}

でも、理由はわかりませんでした。

于 2012-10-24T20:22:00.000 に答える
0

ListItemCollection.GetEnumeratorは、オブジェクトを値として返す.NET1.0以降に使用された列挙子を返します。foreachパターン(Eric Lippertがより詳細に説明しているように)には、GetEnumeratorメソッドを介してオブジェクトから返される列挙子が必要です。

varを使用すると、Current of the Enumeratorはオブジェクトのみを返すため、コンパイラはループ変数のタイプをオブジェクトとして推測します。

public interface IEnumerator
{
    bool MoveNext();
    object Current { get; }
    void Reset();
}

ただし、foreach(ListItem item in xxx)...を使用すると、コンパイラはオブジェクトからListItemにキャストを自動的に追加します。foreach(string str in new object [] {"str"、1})を実行すると、InvalidCastExceptionが発生します。varキーワードに魔法はありません。余分な魔法をかけることなく、単にタイプを推測します。

ループにaが含まれると予想される場合は、ListItemそれを明確に書き出す必要があります。列挙子のメソッドシグネチャからは、どのオブジェクトを返すかは明確ではありません。どのタイプを期待するかをコンパイラに伝える必要があります。コードのリーダーもループ変数のタイプを推測できないため、varキーワードを使用しないもう1つの理由。

于 2012-10-24T21:11:51.970 に答える