Answer
When you call f
, you are in a A<T>
where T
is long
because B
is a A<long>
so T
is long
.
I see why it seems to be weird: you expect that T
is float
, but in fact since B
is A<long>
, B
is a A<T>
where T
is long
.
And because C
is a child of B
, it is an extended same type of B
so a A<long>
.
Therefore the result for the closed constructed type that output long
and not float
that was specified for the generic type parameter of the outer class.
So whatever the T
specified when creating an instance, you will always get long
for the type of T
in f
.
Solving
It's a little complicated recursive innering, I think, but don't you just simply need that?
class A<T>
{
public class B : A<T>
{
public void f()
{
Console.WriteLine(typeof(T).ToString());
}
public class C : B { }
}
}
Thus writing:
var c = new A<float>.B.C();
c.f();
Will output:
System.Single
Readings
Generics open and closed constructed types
Constructed Types
Generics in .NET
Generics (C# Programming Guide)
C# Generics Level 1
C# Generics Level 2