Les objets anonymes sont fortement typés. La seule préoccupation est que vous ne pouvez pas connaître le nom de type (pas directement).
Prenez cet exemple (désolé si elle est trop longue):
static void T2()
{
var x = new
{
a = new { a1 = new Type1("x.1"), a2 = new Type2(1), a3 = new Type3('1') },
b = new { b1 = new Type1("x.2"), b2 = new Type2(2), b3 = new Type3('2') }
};
var y = new
{
a = new { a1 = new Type1("y.1"), a2 = new Type2(1), a3 = new Type3('1') },
b = new { b1 = new Type1("y.2"), b2 = new Type2(2), b3 = new Type3('2') }
};
var z = new
{
a = new { a1 = new Type1("y.1"), a2 = new Type3('1') },
b = new { b1 = new Type3('z'), b2 = new Type2(2) }
};
Console.WriteLine(new string('-', 40));
Console.WriteLine("Anonymous object \"x\" is named {0}.", x.GetType());
Console.WriteLine("Anonymous object \"y\" is named {0}.", y.GetType());
Console.WriteLine("Anonymous object \"z\" is named {0}.", z.GetType());
Console.WriteLine(new string('-', 40));
Console.Write("Anonymous object \"x\" == \"y\"? ");
Console.WriteLine(x.Equals(y) ? "Yes" : "No");
Console.Write("Anonymous object \"x\" == \"z\"? ");
Console.WriteLine(x.Equals(z) ? "Yes" : "No");
var x2 = new
{
a = new { a1 = new Type1("x.1"), a2 = new Type2(1), a3 = new Type3('1') },
b = new { b1 = new Type1("x.2"), b2 = new Type2(2), b3 = new Type3('2') }
};
Console.Write("Anonymous object \"x\" == \"x2\"? ");
Console.WriteLine(x.Equals(x2) ? "Yes" : "No");
// Uncomment it to give:
//Error 1 Cannot implicitly convert type 'AnonymousType#1' to 'AnonymousType#2'
#if GiveMeAnError
z = new
{
a = new { a1 = new Type1("z.1"), a2 = new Type2(1), a3 = new Type3('1') },
b = new { b1 = new Type1("z.2"), b2 = new Type2(2), b3 = new Type3('2') }
};
Console.WriteLine("Anonymous object \"z\" now is named {0}.", z.GetType());
Console.Write("Anonymous object \"x\" == \"z\"? ");
Console.WriteLine(x.Equals(z) ? "Yes" : "No");
#endif
Console.ReadKey();
}
Il produit:
/*----------------------------------------
Anonymous object "x" is named <>f__AnonymousType2`2[<>f__AnonymousType0`3 [anon_obj.Type1,anon_obj.Type2,anon_obj.Type3],<>f__AnonymousType1`3[anon_obj.Type1,anon_obj.Type2,anon_obj.Type3]].
Anonymous object "y" is named <>f__AnonymousType2`2[<>f__AnonymousType0`3[anon_obj.Type1,anon_obj.Type2,anon_obj.Type3],<>f__AnonymousType1`3[anon_obj.Type1,anon_obj.Type2,anon_obj.Type3]].
Anonymous object "z" is named <>f__AnonymousType2`2[<>f__AnonymousType3`2[anon_obj.Type1,anon_obj.Type3],<>f__AnonymousType4`2[anon_obj.Type3,anon_obj.Type2]].
----------------------------------------
Anonymous object "x" == "y"? No
Anonymous object "x" == "z"? No
Anonymous object "x" == "x2"? Yes*/
Chaque composition objet anonyme a son propre nom et définit un type unique. Les objets déclarés avec les mêmes types et les mêmes noms de type vont au même type, comme dans "x == x2". Cependant, l'exemple original est délicat car il définit les tableaux "object []" avec des tableaux "object []" à l'intérieur. De cette façon
var x = new object[ ]
{
new object[] { new Type1("x.1"), new Type2(1), new Type3('1') },
new object[] { new Type1("x.2"), new Type2(2) , new Type3('2')}
};
var y = new object[ ]
{
new object[] { new Type1("y.1"), new Type2(1), new Type3('1') },
new object[] { new Type1("y.2"), new Type2(2) , new Type3('2')}
};
var z = new object[ ]
{
new object[] { new Type1("y.1"), new Type3('1') },
new object[] { new Type3('z'), new Type2(2)}
};
seront tous les mêmes de type (objet []), et la comparaison sera effectuée AllWays en comparant pointeurs, qui, hopefuly, diffèrent.
static void T1()
{
var x = new object[ ]
{
new object[] { new Type1("x.1"), new Type2(1), new Type3('1') },
new object[] { new Type1("x.2"), new Type2(2) , new Type3('2')}
};
var y = new object[ ]
{
new object[] { new Type1("y.1"), new Type2(1), new Type3('1') },
new object[] { new Type1("y.2"), new Type2(2) , new Type3('2')}
};
var z = new object[ ]
{
new object[] { new Type1("y.1"), new Type3('1') },
new object[] { new Type3('z'), new Type2(2)}
};
Console.WriteLine(new string('-', 40));
Console.WriteLine("Anonymous object \"x\" is named {0}.", x.GetType());
Console.WriteLine("Anonymous object \"y\" is named {0}.", y.GetType());
Console.WriteLine("Anonymous object \"z\" is named {0}.", z.GetType());
Console.WriteLine(new string('-', 40));
Console.Write("Anonymous object \"x\" == \"y\"? ");
Console.WriteLine(x.Equals(y) ? "Yes" : "No");
Console.Write("Anonymous object \"x\" == \"z\"? ");
Console.WriteLine(x.Equals(z) ? "Yes" : "No");
var x2 = new object[ ]
{
new object[] { new Type1("x.1"), new Type2(1), new Type3('1') },
new object[] { new Type1("x.2"), new Type2(2) , new Type3('2')}
};
Console.Write("Anonymous object \"x\" == \"x2\"? ");
Console.WriteLine(x.Equals(x2) ? "Yes" : "No");
z = new object[ ]
{
new object[] { new Type1("x.1"), new Type2(1), new Type3('1') },
new object[] { new Type1("x.2"), new Type2(2) , new Type3('2')}
};
Console.WriteLine("Anonymous object \"z\" now is named {0}.", z.GetType());
Console.Write("Anonymous object \"x\" == \"z\"? ");
Console.WriteLine(x.Equals(z) ? "Yes" : "No");
Console.Write("Anonymous object \"x\" == \"z\" (memberwise)? ");
Console.WriteLine(
x[ 0 ].Equals(z[ 0 ])
&& x[ 1 ].Equals(z[ 1 ])
? "Yes" : "No");
Console.ReadKey();
}
Affichera:
/*----------------------------------------
Anonymous object "x" is named System.Object[].
Anonymous object "y" is named System.Object[].
Anonymous object "z" is named System.Object[].
----------------------------------------
Anonymous object "x" == "y"? No
Anonymous object "x" == "z"? No
Anonymous object "x" == "x2"? No
Anonymous object "z" now is named System.Object[].
Anonymous object "x" == "z"? No
Anonymous object "x" == "z" (memberwise)? No
----------------------------------------*/
Voir la Gotcha?
Nice! Un autre exemple de pourquoi j'aime naviguer sur stackoverflow ... Apprenez quelque chose de nouveau chaque jour. Je ne sais jamais à propos de Tuples ... –