C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: LINQ IEnumerable


(過去ログ 164 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■94924 / inTopicNo.1)  LINQ IEnumerable
  
□投稿者/ furu (42回)-(2020/06/04(Thu) 12:40:22)

分類:[C#] 

2020/06/04(Thu) 12:41:51 編集(投稿者)
VS2019 C#

LINQは食わず嫌いでほとんど使用しないからか
いまだによくわかっていません。

以下のプログラムで
IEnumerableなのにLINQを使用できない理由と
解決方法があればを教えてください。

var items = new System.Windows.Forms.ListBox().Items;

var list1 = new List<object>();
foreach (var item in items) list1.Add(item);

var list2 = items.ToList();      //エラー CS1061
var list3 = list1.ToList();      //OK using System.Linq;の確認

【foreach ループを LINQ に変換する】
https://docs.microsoft.com/ja-jp/visualstudio/ide/reference/convert-foreach-linq?view=vs-2019

概要に「IEnumerables を使用する foreach ループを LINQ クエリ…に簡単に変換できます。」
と書いてあり、簡単に変換できましたが
結果は同じでした。

引用返信 編集キー/
■94926 / inTopicNo.2)  Re[1]: LINQ IEnumerable
□投稿者/ Hongliang (1044回)-(2020/06/04(Thu) 12:55:41)
ToListはSystem.Linq.Enumerableに定義されています。
https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.tolist?view=netcore-3.1
このメソッドの引数はIEnumerable<T>型です。

System.Windows.Forms.ListBoxのItemsプロパティはSystem.Windows.Forms.ListBox.ObjectCollection型です。
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.listbox.items?view=netcore-3.1

そしてSystem.Windows.Forms.ListBox.ObjectCollection型を見ると、
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.listbox.objectcollection?view=netcore-3.1
ICollection, IEnumerable, IListのみ実装されていて、IEnumerable<T>が実装されていません。

なのでEnumerable.ToListには渡せません。
// ObjectCollectionがIEnumerable<T>を実装していないのは、この型が定義されたのがジェネリクス採用前であることが大きいです。

IEnumerableからIEnumerable<T>に変換するCast<T>およびOfType<T>という拡張メソッドがEnumerableに用意されています。
これを使えば、
items.Cast<object>().ToList();
form1.Controls.OfType<TextBox>().ToList();
のように記述できます。
なおCastはTにキャストできない要素があれば例外、OfTypeはTにキャストできる要素だけ列挙、という違いがあります。
引用返信 編集キー/
■94927 / inTopicNo.3)  Re[1]: LINQ IEnumerable
□投稿者/ 魔界の仮面弁士 (2740回)-(2020/06/04(Thu) 13:04:23)
No94924 (furu さん) に返信
> 以下のプログラムで
> IEnumerableなのにLINQを使用できない理由と

IEnumerable インターフェイスだから使用できないのです。ジェネリックではないですよね。
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/linq/linq-and-generic-types


System.Linq.Enumerable.ToArray<T> メソッドは、
IEnumerable に対する拡張メソッドではなく、
IEnumerable<T> に対する拡張メソッドであることに注意しましょう。
https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.toarray


> 解決方法があればを教えてください。
.Items.Cast<T>() を使うとか。
引用返信 編集キー/
■94934 / inTopicNo.4)  Re[2]: LINQ IEnumerable
□投稿者/ furu (43回)-(2020/06/04(Thu) 14:41:36)
No94927 (魔界の仮面弁士 さん) に返信
Hongliangさん,魔界の仮面弁士さん
ありがとうございます。
理解できました。

foreach、inのリファレンスにも
「System.Collections.IEnumerable または
System.Collections.Generic.IEnumerable<T>」となっていますね。

    var rows = new DataGridView().Rows;
    foreach (var x in rows){ }
    var y = rows[0];

yはDataGridViewRowなのに
xがobjectなのは
IEnumerable<T>でないからですね。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -