It gets compiled into a generic internal type within your assembly. Something like:
internal sealed class SomeCompilerGeneratedNameHere<T1, T2>
{
public SomeCompilerGeneratedNameHere(T1 test1, T2 test2)
{
...
}
public T1 Test1 { get { ... } }
public T2 Test2 { get { ... } }
// Overrides for Equals, ToString, GetHashCode
}
Then in your case, it would use SomeCompilerGeneratedNameHere<int, int>
. (The name itself is an "unspeakable" name, so you can't refer to it within your code explicitly, and there won't be any naming clashes with valid C# types.)
I can't remember offhand whether the constructor and properties are actually public or whether they're internal too - I know the type itself is internal.
All anonymous types with the same property names in the same order will use the same generic type, just potentially with different type parameters.
Note that this is implementation-specific - I don't believe the specification guarantees that generic types will be used; there could be one type per anonymous type used. The spec does guarantee that two anonymous type creation expressions will use the same type if they have the same property names and types in the same order.