【问题标题】:When I declare a variable as an Interface, and then assign a concrete type to it, where is the declaration type saved?当我将一个变量声明为接口,然后为其分配一个具体类型时,声明类型保存在哪里?
【发布时间】:2017-07-30 05:40:56
【问题描述】:

在下面的代码中,两个对象的类型对象指针都指向整数类型列表。

IEnumerable<int> list1 = new List<int>();
List<int> list2 = new List<int>();

在哪里声明了 list1 的类型(IEnumerable),存储在运行时?

【问题讨论】:

    标签: c# .net types interface


    【解决方案1】:

    不确定它是否回答了您的问题,但它存储在 IL 的 .locals 部分中。

    .maxstack 1
    .entrypoint
    .locals init (
        [0] class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> list1,
        [1] class [mscorlib]System.Collections.Generic.List`1<int32> list2
    )
    
    IL_0000: nop
    IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
    IL_0006: stloc.0
    IL_0007: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
    IL_000c: stloc.1
    IL_000d: ret
    

    但这并不完全是“运行时”。在运行时,JIT 很可能会将其转换为原始指针操作,因此您的答案可能是“无处”。或者,因为编译器在编译时知道变量的类型很重要,所以答案是“在你的源代码中”。

    【讨论】:

    • 当 IL 被 jitted 时。在堆栈中,我们有一个指向对象的指针(它不保存任何类型信息)和堆中的对象本身(它在类型对象指针中保存类型信息,它是List)那么list1和list 2是如何区分?也许“声明”类型只是编译时的?
    • 尊贵是什么意思? list1list2中的指针不同,它们已经指向不同对象的不同接口。无需进一步区分。
    • 区分我的意思是,CLR 是如何知道 list1 是 IEnumerable 而 list2 是 List。这些信息存储在哪里?
    • @Ivak - 该信息不存储在任何地方,只有 C# 编译器需要知道声明类型。
    • 在 JIT 运行之前,它是以静态形式在 IL 中编写的。 JIT 运行后,它不会存储在任何地方,因为它不是必需的。只要 JIT 为您准备好要调用的指针,您就不需要知道要调用的类型。您只需将参数压入堆栈并调用准备好的指针。
    猜你喜欢
    • 1970-01-01
    • 2018-04-28
    • 2017-05-28
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多