匿名型

# 匿名 vs 動的

匿名型を使用すると、事前に型を明示的に定義しなくても、静的な型チェックを維持しながらオブジェクトを作成できます。

var anon = new { Value = 1 };
Console.WriteLine(anon.Id); // compile time error

逆に dynamic コンパイル時エラーの代わりに実行時エラーを選択して、動的型チェックを行います。

dynamic val = "foo";
Console.WriteLine(val.Id); // compiles, but throws runtime error

# 匿名型の作成

匿名型には名前が付けられていないため、これらの型の変数は暗黙的に型指定する必要があります (var ).

var anon = new { Foo = 1, Bar = 2 };
// anon.Foo == 1
// anon.Bar == 2

メンバー名が指定されていない場合、オブジェクトの初期化に使用されるプロパティ/変数の名前に設定されます。

int foo = 1;
int bar = 2;
var anon2 = new { foo, bar };
// anon2.foo == 1
// anon2.bar == 2

名前は、匿名型宣言の式が単純なプロパティ アクセスである場合にのみ省略できることに注意してください。メソッド呼び出しまたはより複雑な式の場合、プロパティ名を指定する必要があります。

string foo = "some string";
var anon3 = new { foo.Length };
// anon3.Length == 11
var anon4 = new { foo.Length <= 10 ? "short string" : "long string" };
// compiler error - Invalid anonymous type member declarator.
var anon5 = new { Description = foo.Length <= 10 ? "short string" : "long string" };
// OK

# 匿名型の同等性

匿名型の等価性は Equals によって与えられます インスタンスメソッド。 2 つのオブジェクトは、同じ型と等しい値 (a.Prop.Equals(b.Prop) まで) を持つ場合、等しいです。 ) すべてのプロパティに対して。

var anon = new { Foo = 1, Bar = 2 };
var anon2 = new { Foo = 1, Bar = 2 };
var anon3 = new { Foo = 5, Bar = 10 };
var anon3 = new { Foo = 5, Bar = 10 };
var anon4 = new { Bar = 2, Foo = 1 };
// anon.Equals(anon2) == true
// anon.Equals(anon3) == false
// anon.Equals(anon4) == false (anon and anon4 have different types, see below)

2 つの匿名型は、それらのプロパティが同じ名前と型を持ち、同じ順序で表示される場合にのみ、同じと見なされます。

var anon = new { Foo = 1, Bar = 2 };
var anon2 = new { Foo = 7, Bar = 1 };
var anon3 = new { Bar = 1, Foo = 3 };
var anon4 = new { Fa = 1, Bar = 2 };
// anon and anon2 have the same type
// anon and anon3 have diferent types (Bar and Foo appear in different orders)
// anon and anon4 have different types (property names are different)

# 匿名型のジェネリック メソッド

ジェネリック メソッドを使用すると、型推論を通じて匿名型を使用できます。

void Log<T>(T obj) {
    // ...
}
Log(new { Value = 10 });

これは、LINQ 式を匿名型で使用できることを意味します:

var products = new[] {
    new { Amount = 10, Id = 0 },
    new { Amount = 20, Id = 1 },
    new { Amount = 15, Id = 2 }
};
var idsByAmount = products.OrderBy(x => x.Amount).Select(x => x.Id);
// idsByAmount: 0, 2, 1

# 匿名型によるジェネリック型のインスタンス化

ジェネリック コンストラクターを使用すると、匿名型に名前を付ける必要がありますが、これは不可能です。あるいは、ジェネリック メソッドを使用して、型を推論できるようにすることもできます。

var anon = new { Foo = 1, Bar = 2 };
var anon2 = new { Foo = 5, Bar = 10 };
List<T> CreateList<T>(params T[] items) {
    return new List<T>(items);
}

var list1 = CreateList(anon, anon2);

List<T>の場合 、暗黙的に型指定された配列は List<T> に変換される場合があります ToList を通して LINQ メソッド:

var list2 = new[] {anon, anon2}.ToList();

# 暗黙的に型指定された配列

匿名型の配列は、暗黙的な型付けで作成できます。

var arr = new[] {
    new { Id = 0 },
    new { Id = 1 }
};