Анонимные объекты строго типизированы .
Единственная проблема заключается в том, что вы не можете знать имя типа (не напрямую).
Возьмите этот пример (извините, если он слишком длинный):
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( );
}
Это выводит:
/*----------------------------------------
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*/
Каждый состав анонимного объекта имеет собственное имя и определяет уникальный тип.
Объекты, объявленные с теми же типами и именами типов, относятся к тому же типу, что и в «x == x2».
Оригинальный пример, однако, хитрый, поскольку он определяет массивы "object []" с массивами "object []" внутри.
Сюда
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)}
};
Все они будут одного и того же типа (объект []), и сравнение будет всегда выполняться путем сравнения указателей , которые, надеюсь, будут отличаться.
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( );
}
Будет выводить:
/*----------------------------------------
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
----------------------------------------*/
Видишь гочу?