【问题标题】:Why does this code replace float with long?为什么这段代码用long替换float?
【发布时间】:2021-01-29 10:38:13
【问题描述】:

我以这段代码为例:

class A<T> {
    public class B : A<long> {
        public void f() {
            Console.WriteLine( typeof(T).ToString());
        }
 
    public class C : A<long>.B { }
    
    } 
}

class Prg5 { static void Main() {
    var c = new A<float>.B.C();
    c.f();
} }

有输出:

System.Int64

为什么要长时间打印类型?最初传递的浮点类型如何以及在何处被替换?

【问题讨论】:

  • 因为B A&lt;long&gt;?
  • 所以在 "new A.B() 中使用浮点数无关紧要?可以放入任何类型并用 long 替换吗?那不应该返回一些错误吗?
  • 对我来说也很奇怪。我希望new A.B.C() 也能正常工作,但显然不能。
  • 我同意,这并不明显。
  • C 是一个A&lt;long&gt;.B,所以T 里面的f()long。未使用 new A&lt;float&gt;.B.C() 中的 float

标签: c# generics types instance inner-classes


【解决方案1】:

C 类型定义为:

public class C : A<long>.B { }

A 类型定义为:

class A<T> {
    public class B : A<long> {
        public void f() {
            Console.WriteLine( typeof(T).ToString());
        }    

    public class C : A<long>.B { }
    } 
}

所以如果你创建一个新的C,那么A 的类型参数就是long

在语句var c = new A&lt;float&gt;.B.C(); 中,A&lt;float&gt;B 只是嵌套类C 的“路径”的一部分。 A&lt;float&gt; 是该路径的一部分这一事实不会改变 CA&lt;long&gt;.B 的事实。

float 参数和BA&lt;long&gt; 的事实与确定Tc.f() 的类型无关。

【讨论】:

  • "只是嵌套类 C 的"路径"的一部分" 这是实际的答案,恕我直言。
  • 我明白了,所以它只需要“任何东西”,因为父类是通用的。我可以使用A&lt;List&lt;string&gt;&gt;.B.C(),它不会改变任何东西。
  • 是的,B 可以是 A&lt;StringBuilder&gt;CA&lt;long&gt;.B 这一事实决定了 c.f()T 的类型。
  • 奇怪的是,如果C继承自B并且拥有自己的f(),那么它返回“Single”。 MSIL 完全相同:ldtoken A&lt;&gt;.T
【解决方案2】:

回答

当您调用f 时,您处于A&lt;T&gt; 中,其中Tlong,因为BA&lt;long&gt;,所以Tlong

我明白为什么这看起来很奇怪:您希望 Tfloat,但实际上因为 BA&lt;long&gt;BA&lt;T&gt;,其中 T 是 @987654342 @。

因为CB 的子代,所以它是B 的扩展相同类型,所以是A&lt;long&gt;

因此,输出long 而不是为外部类的泛型类型参数指定的float 的封闭构造类型的结果。

因此,无论在创建实例时指定的 T 是什么,您总是会在 f 中获得 T 类型的 long

求解

我认为这是一个有点复杂的递归内化,但你不只是需要它吗?

class A<T>
{
  public class B : A<T>
  {
    public void f()
    {
      Console.WriteLine(typeof(T).ToString());
    }

    public class C : B { }

  }
}

这样写:

var c = new A<float>.B.C();
c.f();

将输出:

System.Single

读数

Generics open and closed constructed types

Constructed Types

Generics in .NET

Generics (C# Programming Guide)

C# Generics Level 1

C# Generics Level 2

【讨论】:

  • 我不想改变任何东西,我只是想了解它为什么会输出“System.Int64”。
猜你喜欢
  • 2016-11-30
  • 2013-08-18
  • 1970-01-01
  • 2015-08-31
  • 2011-05-27
  • 1970-01-01
  • 2019-10-05
  • 2014-05-29
  • 2016-09-17
相关资源
最近更新 更多