C# Roslyn c编译器:非托管结构被检测为可空,但我想知道这是否是一个悖论

C# Roslyn c编译器:非托管结构被检测为可空,但我想知道这是否是一个悖论,c#,msbuild,roslyn,C#,Msbuild,Roslyn,突然之间,我发现了一个编译错误,我无法弄清楚,这是关于已经运行了很长时间的代码。这在C7.3中是可复制的。以下结构从未改变: public interface ILocalInputEntityStruct<T> where T : unmanaged { //wouldn't the implementation of this interface prove //that the struct doesn't have nullable fields (so

突然之间,我发现了一个编译错误,我无法弄清楚,这是关于已经运行了很长时间的代码。这在C7.3中是可复制的。以下结构从未改变:

 public interface ILocalInputEntityStruct<T> where T : unmanaged
{
    //wouldn't the implementation of this interface prove 
    //that the struct doesn't have nullable fields (so it's unmanaged for c# 7.3)?
}

public struct LocalInputEntityStruct:ILocalInputEntityStruct<LocalInputEntityStruct>, IEntityComponent, INeedEGID
{
    public float2      cameraAngles; 
    public float       cameraZoomFactor; 
    public float       roll;
    public ActionInput actionMask;
    public GuiInput    guiMask;
}
在以下代码中,在与声明不同的程序集中找到,QueryEntity希望T处于非托管状态,但编译器认为该结构可以为null:

  ref var localInput = ref entitiesDB.QueryEntity<LocalInputEntityStruct>(
                playerId, InputExclusiveGroups.LocalPlayers);
编译此行会导致错误

  VisualCameraInputEngine.cs(60, 53): [CS8377] The type 'LocalInputEntityStruct' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'EntityDBExtensions.QueryEntity<T>(EntitiesDB, uint, ExclusiveGroupStruct)'
现在,我不能肯定这个问题之前就被隐藏了,因为约束在新代码中的工作方式可能不同,但是如果我对编译器工作方式的假设是正确的,那么在我看来这就像是一个悖论。VisualCameraInputEngine.cs不应在LocalInputEntityStruct之前编译,如果LocalInputEntityStruct可为null,则无法编译,对吗?该结构本身是100%非托管的,没有可为空的字段,但由于它是一个复杂的结构,我用非托管约束接口的实现来证明它

编辑:查询实体声明:

 public static class EntityDBExtensions
{
   [MethodImpl(MethodImplOptions.AggressiveInlining)]
   public static ref T QueryEntity<T>(this EntitiesDB entitiesDb, uint id, ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent
   {
       throw new Exception("keeping this code simple for the purpose of the stack overflow question");
   }
}

public static class EntityDBExtensionsB
{
   [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ref T QueryEntity<T>(this EntitiesDB entitiesDb, uint id, ExclusiveGroupStruct group) where T : struct, IEntityViewComponent
    {
        throw new Exception("keeping this code simple for the purpose of the stack overflow question");
    }
}
注意:如果不使用单独的程序集,则编译相同的代码

操作系统信息:

Windows 10,MSBuild 2017 c 7.3

我之所以在这里写作,是因为我正在寻找能够解释为什么会发生这种情况的专家,对此我将非常感激,或者认为这可能是一个Roslyn bug,在这种情况下,我将报告Roslyn github


我不排除我遗漏了一些关于程序集如何工作的信息,我对此一无所知。

Microsoft已确认该问题,解释如下:


代码是文本。错误消息是文本。因此,请将它们作为文本而不是图片。a:这是出于原则。和c一样,它作为文本可读性更好。我们能知道查询实体的定义吗?当它是一种方法,并且一切都起作用时,它是如何定义的?它没有被用作扩展方法。还不清楚QuickSaveEngine.cs是哪个文件。还附议了文本请求-这使得理解问题变得更容易,不需要在图像之间来回点击,这一点很重要,当你要求人们的免费时间时,如果你要打开Roslyn的问题,你需要,所以你可以把一个放在一起:也许解决方案结构是复制的一部分,那很好。但是,你需要经历一个过程,减少哪些是重要的,哪些是不重要的。从您当前的设置开始,并不断删除内容,直到您达到一个点,即如果您进一步删除任何内容,问题不会重现