gpt4 book ai didi

c# - 为什么下面的代码编译执行成功了?

转载 作者:太空狗 更新时间:2023-10-29 21:54:09 26 4
gpt4 key购买 nike

我在 .Net 3.5、Visual Studio 2012 中编译了以下代码。

当数组分配给我的 IReadOnlyCollection 时,我预计会在行中收到错误,因为没有定义从数组到接口(interface)的隐式转换。它编译成功,也不会产生任何运行时错误。

注意事项:

  • 没有引用其他 IReadonlyCollection。所以就得用我的(IReadonlyCollection是.Net4.5加入的,之前的版本没有)
  • 当我将它重命名为 IMyCollection 时,它不再编译
  • 当我更改 namespace 时,它不再编译。

文件1.cs:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Collections.Generic
{
public interface IReadOnlyCollection<T> : IEnumerable<T>, IEnumerable
{
int Count
{
get;
}
}
}

文件2.cs:

using System.Collections.Generic;

namespace ConsoleApplication1
{
public class Test
{
public Test()
{ }
}

class Program
{
static void Main(string[] args)
{
Test[] foo = { new Test(), new Test(), new Test() };


IReadOnlyCollection<Test> bar = foo;

int count = bar.Count;
}
}
}

顺便说一句,这是 IL 代码:

   .method private hidebysig static void Main (
string[] args
) cil managed
{
.entrypoint
.locals init (
[0] class ConsoleApplication1.Test[] foo,
[1] class System.Collections.Generic.IReadOnlyCollection`1<class ConsoleApplication1.Test> bar,
[2] int32 count,
[3] class ConsoleApplication1.Test[] CS$0$0000
)

IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: newarr ConsoleApplication1.Test
IL_0007: stloc.3
IL_0008: ldloc.3
IL_0009: ldc.i4.0
IL_000a: newobj instance void ConsoleApplication1.Test::.ctor()
IL_000f: stelem.ref
IL_0010: ldloc.3
IL_0011: ldc.i4.1
IL_0012: newobj instance void ConsoleApplication1.Test::.ctor()
IL_0017: stelem.ref
IL_0018: ldloc.3
IL_0019: ldc.i4.2
IL_001a: newobj instance void ConsoleApplication1.Test::.ctor()
IL_001f: stelem.ref
IL_0020: ldloc.3
IL_0021: stloc.0
IL_0022: ldloc.0
IL_0023: stloc.1
IL_0024: ldloc.1
IL_0025: callvirt instance int32 class System.Collections.Generic.IReadOnlyCollection`1<class ConsoleApplication1.Test>::get_Count()
IL_002a: stloc.2
IL_002b: ret
}

最佳答案

我所说的只是纯粹的猜测,但它不适合作为评论,所以我还是将其作为答案发布:

  • 我可以使用 VS 2012 和 .Net 3.5 重现您的问题。
  • 我无法使用 VS 2010、.Net 3.5 和相同的代码重现它。

所以区别实际上是编译器版本。

由于类名和命名空间很重要,我假设它是 VS 2012+ 编译器中引入的硬编码规则,以支持 .Net 4.5 引入的新类型/接口(interface)的隐式转换.

所以我猜这是数组的另一个黑魔法。参见示例 this Hans Passant answer :

Both the compiler and the CLR have special knowledge of array types, just as they do of value types. The compiler sees your attempt at casting to IList<> and says "okay, I know how to do that!".

关于c# - 为什么下面的代码编译执行成功了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22378102/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com