質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

940閲覧

C# ToDictionaryメソッドについて

tosa123

総合スコア8

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

1グッド

0クリップ

投稿2022/01/22 03:05

編集2022/01/22 03:11

前提・実現したいこと

本でC#を勉強している際に、ToDictionary()を使う機会があり、その際に公式ドキュメントでもToDictionaryメソッドについて確認していたのですが、

この公式ドキュメントの、ToDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)の部分の参考コードには、以下のように書いてあります。

c#

1 2class Package 3{ 4 public string Company { get; set; } 5 public double Weight { get; set; } 6 public long TrackingNumber { get; set; } 7} 8 9public static void ToDictionaryEx1() 10{ 11 List<Package> packages = 12 new List<Package> 13 { new Package { Company = "Coho Vineyard", Weight = 25.2, TrackingNumber = 89453312L }, 14 new Package { Company = "Lucerne Publishing", Weight = 18.7, TrackingNumber = 89112755L }, 15 new Package { Company = "Wingtip Toys", Weight = 6.0, TrackingNumber = 299456122L }, 16 new Package { Company = "Adventure Works", Weight = 33.8, TrackingNumber = 4665518773L } }; 17 18 // Create a Dictionary of Package objects, 19 // using TrackingNumber as the key. 20 Dictionary<long, Package> dictionary = 21 packages.ToDictionary(p => p.TrackingNumber); 22 23 foreach (KeyValuePair<long, Package> kvp in dictionary) 24 { 25 Console.WriteLine( 26 "Key {0}: {1}, {2} pounds", 27 kvp.Key, 28 kvp.Value.Company, 29 kvp.Value.Weight); 30 } 31} 32 33/* 34 This code produces the following output: 35 36 Key 89453312: Coho Vineyard, 25.2 pounds 37 Key 89112755: Lucerne Publishing, 18.7 pounds 38 Key 299456122: Wingtip Toys, 6 pounds 39 Key 4665518773: Adventure Works, 33.8 pounds 40*/ 41 42 43

このメソッドの説明にはIEnumerable<TSource>と、 Func<TSource,TKey>の引数2つが利用されていると思うのですが、参考コードにはp => p.TrackingNumberのラムダ式の関数の引数1つしか代入されておらず、引数としてIEnumerable<TSource>を代入していないのに何故機能するの…?と純粋に疑問に思ってしまったのですが、なぜ代入していなくても大丈夫なのでしょうか。第一引数でも引数の省略が可能だったりするのでしょうか。初歩的な質問ですみません、ご回答宜しくお願い致します。

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2022/01/22 03:53

p と TrackingNumber の二つあります。
tosa123

2022/01/22 04:12

Func<TSource,TKey>に、ラムダ式(p => p.TrackingNumber)が当てはまっていて、Tsourceが引数p、TKeyが返り値のp.TrackingNumberと自分では解釈していて、ToDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)の引数の部分にそのまま当てはめると、 (IEnumerable<TSource>, p => p.TrackingNumber)となって、参考コードだと、IEnumerable<TSource>に何も代入されていないのでは?と感じたのですが…、 このコードだと、IEnumerable<TSource>はpを指しているという事になるのでしょうか…?となると、Func<TSource,TKey>は、p.TrackingNumberを指しているという事になるのでしょうか…?
Zuishin

2022/01/22 05:00

拡張メソッドですね。TN8001 さんが言及されているので、そちらをご覧ください。
tosa123

2022/01/22 05:02

理解できました。ありがとうございました!
guest

回答1

0

ベストアンサー

これですね。
Enumerable.ToDictionary メソッド (System.Linq) | Microsoft Docs

その前にこのメソッドは、どのクラスのメソッドでしょうか?

そのページの先頭に「Enumerable.ToDictionary メソッド」と書いてあります。
あるいはそのさらに上に↓のようなリンクもある通り、このメソッドはEnumerableクラスのメソッドです。

Docs / .NET / .NET API ブラウザー / System.Linq / Enumerable / メソッド / ToDictionary

Enumerable クラス (System.Linq) | Microsoft Docs

そのうえstaticがついています。

cs

1public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

つまり本来は↓こう使用するはずなのです。

cs

1Dictionary<long, Package> dictionary = Enumerable.ToDictionary(packages, p => p.TrackingNumber);

ですが、C#の言語機能(拡張メソッド)で、packages.ToDictionary(p => p.TrackingNumber);と書いても同じ意味になるのです(第一引数の頭にあるthisがポイントです)
拡張メソッド - C# プログラミング ガイド | Microsoft Docs
拡張メソッド - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

既存の型に後からメソッドを追加できる(ように見える)大変便利な機能で、LINQはほぼすべて拡張メソッドで実装されています。

using System.Linq;を忘れると、一切使えなくなるので注意です。

投稿2022/01/22 04:31

編集2023/07/29 14:39
TN8001

総合スコア9321

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tosa123

2022/01/22 05:00

非常に分かりやすく、手順を追って説明してくださってありがとうございます! thisを見ても、正直何となくそのままスルーしてしまったのですが、拡張メソッドの意味合いがあったのですね…。(スルーせずもう少し自分で調べるべきでした…。) 以前、拡張メソッドに関して触れる機会はあったのですが、当時はいまいちよく分からず軽く本で読み飛ばしていた部分でした。linqに関しても、「すごい便利だ!書きやすいし、見やすい!」位でしか使っていなかったので、拡張メソッドのような背景もあってlinqが成り立っている事を知りませんでした…。 理解できました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問