最近、私はC#で非常に驚くべき動作を見出しました。 私はパラメータとしてIEnumerable<Object>
を受け取り、私は IEnumerable<string>
を渡すメソッドを持っていましたが、それはできません。 C#では、なぜこれができないのか、Objectにアップキャストできますか? それは私のために完全に混乱しています。 誰かがこの問題について私を明確にしてください。IEnumerable <Object>からIEnumerableへのキャスト<string>
答えて
これの専門用語は、C#3.0以前ではジェネリックは不変であるということです。 C#4.0以降では、キャストが機能します。
不変の意味は、汎用タイプのパラメータが関連している(つまり、互いにサブタイプまたはスーパータイプである)という理由だけで、2つのジェネリックタイプ間には関係がないことを意味します。
この例では、文字列がオブジェクトのサブタイプであるため、IEnumerable<object>
とIEnumerable<string>
の間にはタイピング関係はありません。文字列とintのような完全に無関係な2つの型とみなされています(これらはどちらもオブジェクトのサブタイプですが、すべてがあります)
実行したこの問題に対するいくつかの回避策と例外があります。
まず、個々の文字列を個別にオブジェクトにキャストできます。.NET 3.0を使用している場合は、Cast<T>()
拡張メソッドを使用して行うことができます。それ以外の場合は、foreachを使用して、結果を必要な静的型の新しい変数に入れることができます。
第2に、配列は参照型の例外です。つまり、オブジェクト[]型を認識するメソッドに文字列[]型を渡します。型は機能します。
だけに: –
あなたは
IEnumerable<T>
を使用する必要がありますが、異なる種類に渡したい場合は、その後、あなたはそれの型を調べるためにTを照会することができます。
これについて考える良い方法は、「これを行うことができたらどうなりますか?」と自分自身に問いかけることです。次の例をご覧ください:
IEnumerable<String> strings=...;
IEnumerable<Object> objects = strings; // assume this were legal
objects.Add(new Integer(5)); // what the...
文字列のリストに整数を追加しました。コンパイラは、型の安全性を保持するためにこれを行います。
IEnumerable
さらに、ListのようなAddメソッドを持つジェネリッククラスを置き換えてください。 –
-1: 'IEnumerable
IEnumerable<object>
を要する機能するIEnumerable<string>
を通過する最も簡単な方法は、このような変換機能を介してである:
public IEnumerable<object> convert<T>(IEnumerable<T> enumerable)
{
foreach (T o in enumerable)
yield return o;
}
C#4が出た場合、それは共変性と反変性をサポートするので、これは、neccessaryされません。
これは><キャスト:) –
のためのおかげで、まさにです!私はすでに、この、この提案の答えをupvoted。 –
他の人が指摘しているように、ジェネリック型は不変です。 IEnumerable<T>
は共変種であることがありますが、C#は現在、変種の指定をサポートしていません。 C#4.0ではバリアントのサポートが予定されているため、将来サポートされる可能性があります。
これを回避するには、LINQ拡張方法Cast<object>()
を使用できます。 Foo
というメソッドがあり、それにはIEnumerable<object>>
が必要だとします。
Foo(stringEnumerable.Cast<object>());
- 1. IEnumerableからIEnumerableへのキャスト<object>
- 2. `IEnumerable <Unknown T>`を `IEnumerable <Whatever>`にキャストする方法
- 3. キャストIEnumerable <T>ランタイムタイプ
- 4. SqlDataReaderからIEnumerableへ<T>
- 5. Transform IEnumerable <Dto> to IEnumerable <ViewModel>
- 6. IEnumerableをにキャストする<T>
- 7. リストから選択する方法<IEnumerable <ItemClass>>〜IEnumerable <ItemClass>?
- 8. リスト<int>からIEnumerable <IComparable>
- 9. IEnumerableとIEnumerableの違い<T>?
- 10. Mapper.Map <タスク<IEnumerableを<Address>>、タスク<IEnumerableを<AddressView>>()
- 11. 重複したIEnumerableを削除するIEnumerable <IEnumerable <T>>
- 12. IEnumerableへのMembershipUserCollection <MembershipUser>のページング
- 13. 型引数Enumerable.Zip(IEnumerableを 'Enumerable.Zip <TFirst、TSecond、TResult>(<TSecond> IEnumerableを、<TFirst> IEnumerableを、funcが<TFirst、
- 14. IEnumerable <struct>をIEnumerable <object>としてキャストできないのはなぜですか?
- 15. IEnumerableを<TParent>
- 16. を比較するIEnumerable <T>をIEnumerable <IEnumerable <T>>効率的に
- 17. IEnumerableの問題<TEntity>
- 18. を型「のIEnumerableを<>」
- 19. オブジェクトをIEnumerable <object>にキャストしますか?
- 20. IEnumerableでカウント<dynamic>
- 21. キャスティングIEnumerable <dynamic>カスタムクラス
- 22. IEnumerable <T> vs IReadOnlyList
- 23. IEnumerableを<T>質問
- 24. Fast IEnumerable <enum1>リストへ<enum2>変換
- 25. LINQ:別のIEnumerable <T>からIEnumerable <T>を作成していますか?
- 26. 入れ子のインターフェイス:IDictionary <TKey、IEnumerable <TValue>>にIDictionary <TKey、IList <TValue>>をキャストしますか?
- 27. 受信したオブジェクトをList <object>またはIEnumerable <object>にキャスト
- 28. List <IEnumerable <ProductViewModel >>を<IEnumerable <ProductViewModel >>に変換する方法は?
- 29. IEnumerableをIEnumerableに変換する<T>
- 30. ラムダ型をint => IEnumerable <string>> int =>タスク<IEnumerable <string> >>に変換しますか?
どのようにすることはできませんか?それは、ArgumentExceptionがを投げていますか?また、あなたがオブジェクトとしてそれを宣言するつもりならジェネリックのIEnumerableを使用してのポイントは何ですか? http://stackoverflow.com/questions/6557/in-c-why-cant-a-liststring-object-be-stored-in-a-listobject-variable –
それは同じコンパイルエラー –
です更新この古い答えは、共変性と反変性は現在、C#でサポートされており、これは現在有効なキャストです。 –