[英]Roslyn c# compiler: unmanaged struct is detected as nullable, but I wonder if it's a paradox
突然之间,我在已经运行了很长时间的代码上出现了一个我无法弄清楚的编译错误。 这可通过 C# 7.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 是非托管的,但编译器认为该结构是可以为空的:
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可以为空,则不能编译,对吧? struct 本身是 100% 非托管的,并且没有可为空的字段,但由于它是一个复杂的结构,因此具有非托管约束的接口的实现是我证明它的方法。
编辑: QueryEntity声明:
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 错误(在这种情况下,我将在 Roslyn github 上报告)。
我不排除我错过了关于程序集如何工作的一些东西,我对此一无所知。
微软已经承认了这个问题,解释在这里:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.