簡體   English   中英

Roslyn c# 編譯器:非托管結構被檢測為可為空,但我想知道這是否是一個悖論

[英]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 上報告)。

我不排除我錯過了關於程序集如何工作的一些東西,我對此一無所知。

微軟已經承認了這個問題,解釋在這里:

https://github.com/dotnet/roslyn/issues/46003

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM