Generics C#8.0编译器或.NETCore3运行时中的Bug?

Generics C#8.0编译器或.NETCore3运行时中的Bug?,generics,c#-8.0,.net-core-3.1,default-interface-member,verificationexception,Generics,C# 8.0,.net Core 3.1,Default Interface Member,Verificationexception,我想我可能在C#8.0编译器或.NET核心运行时中发现了一个关于默认接口成员实现和泛型类型参数约束的问题 它的一般要点是,我实现了一个非常简单的设计,您可以使用它来重现运行时VerificationException,这是我在运行一段代码时得到的,该代码编译得很好,实际上应该很好 让我们来看看代码。我创建了一个包含两个项目的空白解决方案:一个C#library targeting.NETStandard 2.1和一个C#test project targeting.netcore 3.1,其中测

我想我可能在C#8.0编译器或.NET核心运行时中发现了一个关于默认接口成员实现和泛型类型参数约束的问题

它的一般要点是,我实现了一个非常简单的设计,您可以使用它来重现运行时VerificationException,这是我在运行一段代码时得到的,该代码编译得很好,实际上应该很好

让我们来看看代码。我创建了一个包含两个项目的空白解决方案:一个C#library targeting.NETStandard 2.1和一个C#test project targeting.netcore 3.1,其中测试项目引用库

然后在库项目中,我添加了以下代码:

//在库项目中
命名空间库
{
公共接口IMessageHandler{}
公共接口
{
void DoSomething(),其中TMessageHandler:class,IMessageHandler=>
DoSomething(“某物”);
void DoSomething(字符串值),其中TMessageHandler:class,IMessageHandler;
}
公共密封类SomeClass:接口
{
public void DoSomething(字符串值),其中TMessageHandler:class,IMessageHandler{}
}
}
注意
DoSomething
-方法如何在
TMessageHandler
上声明泛型类型约束,该约束也引用接口的泛型类型参数
TMessage

在测试项目中,我添加了
IMessageHandler
接口(
SomeHandler
)的存根实现,以使某个类型满足泛型类型参数约束。然后,我实现了下面的简单测试,该测试调用了具有默认实现的
接口.DoSomething
的重载(注意:我使用MS-test):

//在测试项目中。
使用Microsoft.VisualStudio.TestTools.UnitTesting;
命名空间库。测试
{
[测试类]
公共密封类测试
{
[测试方法]
公共无效DoSomething_doesmething()
{
CreateSomeClass().DoSomething();
}
私有静态接口CreateSomeClass()=>
新类();
}
公共密封类SomeHandler:IMessageHandler{}
}
正如您所预料的,这一切编译得很好

但是,当您运行此测试时,CLR在调用
DoSomething
-方法时抛出
VerificationException

System.Security.VerificationException:方法接口'1[System.Object].DoSomething:类型参数'TMessageHandler'违反了类型参数'TMessageHandler'的约束

这就好像运行时看不到类
SomeHandler
实际上满足了这个约束——编译器已经检查了这个约束

经过一点实验,我注意到如果我将类型参数约束更改为不依赖/使用接口的类型参数
TMessage
,问题就会消失。例如,如果我只是省略了
TMessageHandler
实现
IMessageHandler
的要求,那么代码运行得很好:

公共接口
{
void DoSomething(),其中TMessageHandler:class=>
DoSomething(“某物”);
void DoSomething(字符串值),其中TMessageHandler:class;
}
还可以添加其他约束,只要它们不使用
TMessage

还要注意的是,如果我保持泛型类型参数约束不变,但将方法的实现移动到
SomeClass
——这是在C#8.0之前应该做的——那么代码也可以正常运行,因此正是这种约束和默认接口方法实现的特殊组合导致了系统崩溃


这是编译器或CLR中的一个错误,还是我在思考过程中遗漏了一个重要步骤?

我相信这是一个重复的错误,然后被解析为一个错误


它看起来还没有被修复,但是有一个里程碑需要在.NET 5.0中修复。

我相信这是一个复制品,后来被解析为一个


它看起来还没有被修复,但是有一个里程碑需要在.NET 5.0中修复。

这个问题最近在中得到了解决。

这个问题最近在中得到了解决。

我很难遵循这些复制步骤。什么是
IMyInterface
?我看不到任何地方定义了
IMyInterface
。这些步骤似乎混淆了“My”和“Some”类/接口。在
Main
中触发运行时异常的实际上是什么。如果你能在每个项目的一个代码块中提供所有的代码,那么事情就会变得简单,所以这是一个“复制、粘贴、编译”的问题。@vcsjones是的,对此很抱歉-我在代码中进行了一系列迭代,混淆了命名-我现在修复了它。我还将所有代码添加到两个单独的块中,这样您就可以复制粘贴并运行。我使用MS Test来运行代码。@JonSkeet thnx获取提示-请参阅我上面的评论。这实际上取决于MS Test吗?虽然现在这并不难做到,因为有各种各样的测试框架,但许多人并不熟悉任何一个特定的框架。除非这实际上是关于测试的,否则拥有一个类库和一个控制台应用程序会更简单。我现在就试试。我很难遵循这些复制步骤。什么是
IMyInterface
?我看不到任何地方定义了
IMyInterface
。这些步骤似乎混淆了“My”和“Some”类/接口。在
Main
中触发运行时异常的实际上是什么。如果你能在每个项目的一个代码块中提供所有的代码,那么事情就会变得更简单,所以这是一个“复制、粘贴、编译”的问题。@vcsjones是的,对此很抱歉-我在一系列迭代中混淆了命名