20

List<AnonymousObject>aを aにキャストできないのはなぜList<dynamic>ですか? 私はこの次のコードを持っています:

var datasource = someList.Select(o => new { x = o.A, y = o.B });
dgvSomeGridView.DataSource = datasource.ToList();
dgvSomeGridView.DataBind();

GridView.DataSource次に、次のコードでアクセスします。

var ds = ((List<dynamic>)dgvSomeGridView.DataSource);
....

しかし、それをキャストした行でエラーがスローされ、次のように表示されList<dynamic>ます。

System.Collections.Generic.List'1[<>f__AnonymousType0'8[System.Int32,System.String]]タイプ のオブジェクトを タイプにキャストできませんSystem.Collections.Generic.List'1[System.Object]

匿名型のリストを にキャストできないのはなぜですかdynamic、またはエラーが示すように型にキャストできませんobjectか? どうすればこれを解決できますか?

私のコードは C#、フレームワーク 4.0、VS2010 Pro でビルド、プラットフォームは ASP.NET です。

助けてください、事前に感謝します。

4

2 に答える 2

49

List<T>は共変ではなく不変なので、共変をサポートするものにキャストする必要があります。IEnumerable<dynamic>

var ds = ((IEnumerable<dynamic>)dgvSomeGridView.DataSource).ToList();

共変の詳細については

于 2013-04-24T03:50:20.710 に答える
9

まず、ジェネリックを使用したキャストはそのようには機能しません。このキャストは無効です:

List<string> source = GetStrings();
List<object> source2 = (List<object>) source;

その理由は、 List が共変ではないからです。もしそうなら、source2.Add(source2);source1 は、文字列のみを持つべきときに突然それ自体を含むことができます。

第二に、匿名型は、読み取り専用プロパティと値の等価性セマンティクスを持つコンパイラで宣言されたクラスにすぎません。読み取り専用プロパティと値等価セマンティクスを使用してクラスを作成した場合、クラスは匿名型と同じになりますが、型には開発者が決定した名前が付けられ、匿名型にはコンパイラが決定した名前が付けられます。Anon 型は特別なものではありません。

第 3 に、 動的変数は、コンパイラの型チェックを回避する方法です。実行時の型チェックを回避しません。C# キャスト構文を使用して、型を動的に明示的に変換できます... 注: これはキャストではありません! 実行時に存在しない型にランタイム キャストを実行することはできません。

ただし、dynamic 型の式を含む操作は、コンパイラによって解決または型チェックされません。コンパイラは操作に関する情報をまとめてパッケージ化し、その情報は後で実行時に操作を評価するために使用されます。プロセスの一部として、dynamic 型の変数は object 型の変数にコンパイルされます。したがって、タイプ dynamic は、実行時ではなく、コンパイル時にのみ存在します。

static void convertToDynamic()
{
    dynamic d;
    int i = 20;
    d = (dynamic)i;
    Console.WriteLine(d);

    string s = "Example string.";
    d = (dynamic)s;
    Console.WriteLine(d);

    DateTime dt = DateTime.Today;
    d = (dynamic)dt;
    Console.WriteLine(d);

}
// Results: 
// 20 
// Example string. 
// 2/17/2009 9:12:00 AM

最後に、それでも が必要な場合は、次のようList<dynamic>にします。

var anonList = GetAnonList();
List<dynamic> dynamicList = anonList.Select(x => (dynamic)x).ToList();

しかし、次のように簡単に行うことができます。

var anonList = GetAnonList();
List<object> objectList = anonList.Cast<object>().ToList();
于 2013-04-24T03:52:59.303 に答える