こんにちは。今回もよろしくお願いします。
前提・実現したいこと
下図の構成のようなListがあります。(LINQで作成)
構成は維持したまま、c[]内のresult 全てに対して、Choiseの値をキーにして昇順にソートを掛けたいのですが
エラーとなってしまいます。
式ツリー型にキャストすれば解決するのではという予測はついているのですがどのようにキャストするのか見当が付きません。
該当のソースコード
C#
1 c.ForEach(x => x.result.Sort((a,b) => string.Compare(a.Choise,b.Choise))); 2
発生している問題・エラーメッセージ
ラムダ式を最初にデリゲート型または式ツリー型にキャストせずに、動的にディスパッチされる操作の引数として使用することはできません ※(a,b) => string.Compare(a.Choise,b.Choise) 部分に波線
補足
LINQで求めているなら、orderbyをすればよいのでは と思われるかもしれませんが、
LINQで求めたのちにListに対してadd処理を行っている為、再度sortしなおす必要があると考えています。
2020/3/23/16:58追記
より本番環境に近い形のサンプルコードを作成しました。
C#
1 private void test() 2 { 3 4 List<string[]> data1 = new List<string[]>(); 5 6 7 List<dynamic> c = new List<dynamic>(); 8 9 10 data1.Add(new string[2] { "1.aaa", "2.aaa" }); 11 data1.Add(new string[2] { "3.bbb", "2.bbb" }); 12 data1.Add(new string[2] { "2.ccc", "1.ccc" }); 13 14 15 int item_count = 0; 16 for (int j = 0; j < 2; j++) 17 { 18 19 c.Add(new 20 { 21 title = j.ToString() + ".test", 22 result = data1.GroupBy(x => x[item_count]) 23 .Select(x => new { Choise = x.Key, Count = x.Count() }) 24 .ToList() 25 }); 26 27 item_count++; 28 29 } 30 31 foreach (var item in c) 32 { 33 List<dynamic> list = item.result; 34 list.Sort((a, b) => string.Compare(a.Choise, b.Choise)); 35 } 36 }
2020/3/23/14:55追記 (廃止)
以下誤りです.
ご指摘により該当のListを作成するコードを作成しました。
C#
1 private void test() 2 { 3 4 List<dynamic> c = new List<dynamic>() { 5 new { 6 result = new List<dynamic>() 7 { 8 new { Choise ="01.やまだ", Count = 1}, 9 new { Choise ="03.さとう", Count = 3}, 10 new { Choise ="02.やまもと", Count = 4} 11 }, 12 title = "1.test" 13 14 }, 15 new { 16 result = new List<dynamic>() 17 { 18 new { Choise ="01.aaa", Count = 1}, 19 new { Choise ="03.bbb", Count = 3}, 20 new { Choise ="02.ccc", Count = 4} 21 }, 22 title = "2.test" 23 } 24 }; 25 26 // c.ForEach(x => x.result.Sort((a, b) => string.Compare(a.Choise, b.Choise))); 27 28 29 }
同じリストを回答者の手元で作れる短いコードを作って載せると解決が早いでしょう。
Zuishin様
ご指摘ありがとうございます。スモールコード作成しますので少々お待ちください
Zuishin様
作成しました。
dynamic型ではない静的な型を値(掲示されたコードでいうc)に持たせるのは難しいでしょうか。(データの取得元はJSONか何かでしょうか)
追記:動的か静的かはこの質問の本題ではなさそうなので、スルーでお願いします
これならわかりやすいです。誰か答えてくれるでしょう。こんなことはないと思いますが、もし長期間回答がつかないようなら私も試してみます。
LINQ 一発では無理で、ループ中で result を List<dynamic> にキャストしてソートするというのを result の回数だけ行えばできそうに思います。
> 既存プログラムの大部分で共用
本題から離れていると承知の上でコメントしますが、稼働中のプログラムだからこそdynamicはやめてクラスなり匿名型なりValueTupleなりに変更する方が良いと思います。これではコンパイルエラーが起きないので、未然にバグを防げません。
> 元の構成を変えてしまうと修正と検証に工数がかかってしまうため、本件に関しては構成を維持したままというところを前提とさせていただければと思います。
例えcのコレクションが持つ要素の型が静的な型に変わっても、他の参照箇所が正しく動いていたならコンパイルエラーは発生しないはずです。(つまり、影響としてはほとんどゼロの認識)
もし発生するならそこは元々正しく動かなかっただけであり、dynamicを使ったことによる弊害が出ていることになります。
この弊害をスルーすることによって今後技術的な負債を抱えるリスクがある。そのリスク対応に対して今dynamicを直す以上の工数がかかる可能性がある。ということを念頭に入れた上で構成を維持すべきかどうかは判断すべきだと思います。

回答5件
あなたの回答
tips
プレビュー