Think of it this way:
class C { private const int BigSecret = 0x0BADFOOD; public static void M() { DX(BigSecret); } } class D { public static void X(int y) { Console.WriteLine(y); } }
When CM is called, DX learns the secret and shares it with the world. The fact that BigSecret is private does not matter; you conveyed its meaning. The code is not forbidden to see the value of the private field, it is forbidden using the name of the private field. X is completely free to use the value of y at his discretion; he is not doing anything illegal, for example, trying to use the name BigSecret.
Type arguments are similar. They logically pass arguments to a common function. Of course, they are not transmitted using the same mechanisms under the hood, but logically they simply pass arguments that set the values โโof the type parameter, just like regular arguments set the values โโof formal parameters. If you do not want to pass a secret private type, do not pass it as a type argument.
In your case, StoreTheData is not allowed to use the name PrivateClass, but if you pass the value PrivateClass, it can use whatever it wants. If you do not want it to be used, you should not have skipped it. Just as if you did not want BigSecret to be known, then you should not transmit it. A secret shared is no longer a secret.
By the way, we use the fact that the generic type does not check the availability of its type parameters in order to make anonymous types. For more information, see my article on this topic:
http://blogs.msdn.com/b/ericlippert/archive/2010/12/20/why-are-anonymous-types-generic.aspx
source share