【发布时间】:2014-03-13 12:05:23
【问题描述】:
我在 .Net 3.5、Visual Studio 2012 中编译了以下代码。
当数组被分配给我的 IReadOnlyCollection 时,我预计会出现错误,因为没有定义从数组到我的接口的隐式转换。 它编译成功,也不会产生任何运行时错误。
注意事项:
- 没有引用其他 IReadonlyCollection。所以它必须使用我的(IReadonlyCollection 已添加到 .Net4.5 中,在早期版本中不存在)
- 当我将它重命名为 IMyCollection 时,它不再编译了
- 当我更改命名空间时,它不再编译。
文件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
}
【问题讨论】:
-
可能你有一些新的编译器,它知道如何将数组作为只读集合使用,它会生成一些额外的代码来转换它。您可以通过使用 ildasm util 验证已编译类的 IL 来检查它
-
您能否仔细检查您实际针对的是哪个平台?我无法重现这个。 (VS2010,Fx 3.5)
-
@HenkHolterman VisualStudio 2012。我选择了一个 .Net3.5 控制台应用程序
-
另外作为一个思路,能不能在最后加上Console.WriteLine(bar.GetType())?我不确定它会输出 System.Array
-
@rudimenter 正如 ken2k 的回答所涵盖的那样,您似乎只是偶然发现了秘密编译器短语,它可以让您在语言/工具支持赶上之前做这种事情:-) Jon Skeet 做到了
async/await.
标签: c# arrays .net-3.5 implicit-conversion