c# - IEnumerable へのオブジェクト

okwaves2024-01-25  8

閉まっている。この質問は再現できないか、タイプミスが原因です。現在回答を受け付けておりません。

この質問はタイプミスまたは再現できない問題によって発生しました。同様の質問がここで取り上げられている可能性がありますが、この質問は将来の読者を助ける可能性が低い方法で解決されました。

3 年前

に閉鎖されました。

この質問を改善してください

この質問でこんなに悩むとは思っていませんでしたが、数時間の実験と Google 検索の結果、ここにたどり着きました。値が int と double の配列であるハッシュテーブルがあります。ハッシュテーブルの内容をdoubleの配列として処理したいと考えています。試したことすべてが無効なキャスト例外を引き起こします。

ここで私が試したことの例をいくつか示します。

var h = new Hashtable() { { "Integer", new[] { 1, 2 } }, { "Double", new[] { 2.0, 3.0 } };

// Just cast it to a double
var d = (h.Keys as IEnumerable).Cast<double>(); // Invalid cast exception when enumerating

// Maybe casting to an object first will resolve the casting issues?
var d1 = (h.Keys as IEnumerable).Cast<object>().Cast<double>(); // Invalid cast exception when enumerating

h のすべての値を double として扱うにはどうすればよいですか?

8

HashTable やその他の非汎用データ構造は使用しないでください。それは何百万もの異なる問題を引き起こすだけです。

– サービス

2020 年 9 月 4 日 18:18

3

"新規開発に Hashtable クラスを使用することはお勧めしません。代わりに、汎用の Dictionary を使用することをお勧めします。クラス。」辞書 ...ハッシュテーブル

– クアバアム

2020 年 9 月 4 日 18:23

@Servy と @quaabamm はまったく正しいです。 HashTable は使用しないでください。ただし、適切な Dictionary<K, V> を使用しても、新しい Dictionary<string, Dynamic[]>().Keys.Cast<double>() を記述することはできます。キーを設定しているため、キーが文字列であることがわかっている場合にそれを行いますか?

– アルアン・ハダッド

2020 年 9 月 4 日 18:29

2

@AluanHaddad 明らかに間違いです。この間違いは、すべてをキャストする必要があり、型を間違えたときにそれを教えてくれるコンパイラがない場合に、はるかに犯しやすくなります。

– サービス

2020 年 9 月 4 日 18:41

6

@AluanHaddad 彼はキーと値を混同したと思います。

– insane_developer

2020 年 9 月 4 日 18:45



------------------------

代わりに辞書を使用してみてはいかがでしょうか

var h = new Dictionary<string, object[]>() {
    {"Integer", new object[] {1, 2, 3}},
    {"Double", new object[] {1.0, 2.0,3.0}
}};

var doubles = h.SelectMany(i => i.Value)
               .Select(i => Convert.ToDouble(i));
Console.WriteLine(string.Join(", ", doubles));

不必要な変換を避けるために、このようにコンパイラにハードな作業を実行させることができます。

var h = new Dictionary<string, double[]>() {
    {"Integer", new [] {1d, 2, 3}},
    {"Double", new [] {1.0, 2.0,3.0}
}};

Console.WriteLine(string.Join(", ", h.SelectMany(i => i.Value)));

または、HashTable を使用してデータ構造を維持する必要がある場合

var h = new Hashtable() { { "Integer", new[] { 1, 2 } }, { "Double", new[] { 2.0, 3.0 } } };

var doubles = h.Values.OfType<int[]>()
                    .SelectMany(i => i).Select(i => Convert.ToDouble(i))
                    .Concat(h.Values.OfType<double[]>().SelectMany(i => i));
Console.WriteLine(string.Join(",", doubles));

ただし、Dictionaries は汎用コレクション (System.Collections.Generic 名前空間) であり、より高速で、Linq 構文を使用してデータを簡単に操作できるため、Dictionaries に切り替えることをお勧めします。

12

2

object[] 型の配列に値を格納するのはなぜですか?なぜ正確なタイプを使用しないのでしょうか?

– ザック・イソワール

2020 年 9 月 4 日 18:36

1

値が同じ型ではないため、辞書はいずれかを指定する必要があります。ジェネリックを使用する場合は、辞書なしで別のコレクションが必要になります。

– insane_developer

2020 年 9 月 4 日 18:38

1

いいですね! OP の利益と答えの完全性のために、Hashtable を使用しない理由の説明を追加します。コメントにリンクがあることは承知していますが、回答の説明としても役立つと思います。

– クールボット

2020 年 9 月 4 日 18:40

1

@SerOPによれば、彼には2つの異なるタイプがあります。だからこそ、object[] を使用することにしました。

– ルイス・ラビエリ

2020 年 9 月 4 日 18:41

3

@LuisLavieri しかし、それらが 2 つの異なるタイプである必要があるでしょうか?彼らは全員がダブルスであることを特に望んでいると述べた。それらが同じ型ではないということは、まさに解決しようとしている問題であり、不適切な形式で型を作成して実行時に再作成するのではなく、静的に解決できる問題です。ずっと望んでいたものに..

– サービス

2020 年 9 月 4 日 18:43



------------------------

HashTable の Keys プロパティは文字列「Integer」にすぎません。と "Double" なので、残念ながら、はい、文字列 "Integer" をキャストしようとしています。 double にすると例外がスローされます。

HashTable インスタンスの Values プロパティを使用してみてください。各値には独自の型があります。この場合、int[] と double[] は、h.Values 自体が ICollection に他ならず、IEnumerable も実装します。つまり、ご存知のとおり、Linq Cast 拡張メソッドを使用できます。

言及する価値はありますが、この方法で行うことは決して推奨しません (多くの人が提案しているように、IDictionary を使用する方がはるかに便利かもしれません)。 int と double の両方が IComparable インターフェイスを実装しているため、あなたの質問に対する答えは次のとおりだと思います。 /p>

 h.Values
  .Cast<Array>()
  .SelectMany(a => a.Cast<IComparable>())
  .Select(c => Convert.ToDouble(c))

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。