簡體   English   中英

在構建到 UWP 和 Il2CPP 后,通用方法中的 AOT(提前)出現問題

[英]Problem with AOT (ahead of time) in a generic method after built to UWP and Il2CPP

我有一個通用方法,用於嘗試使用我自己的TryGetValue之類的鍵通過鍵從字典中獲取通用值(當然,對基本內容進行了很多裁剪)

public class BaseExample
{
    public virtual bool TryGetValue<T>(string key, out T value)
    {
        value = default;
        return false;
    }
}

public class Example : BaseExample
{
    private Dictionary<string, Item> _items = new Dictionary<string, Item>();

    public override bool TryGetValue<T>(string key, out T value)
    {
        value = default;
        if (!GetItem(key, value, out var setting)) { return false; }

        value = (T)setting.Value;
        return true;
    } 

    private bool GetItem<T>(string key, T value, out Item item)
    {
        item = null;

        if (!_items.ContainsKey(key))
        {
            item = null;
            return false;
        }

        item = _items[key];

        return true;
    }
}

這在 Unity 編輯器中有效,但是一旦我嘗試使用 eg 運行該方法,它就會構建為 UWP 和 IL2CPP

var value = example.TryGetValue<int>("SomeKey");

它拋出一個

 System.ExecutionEngineException: Attempting to call method 'Example::TryGetValue<System.Int32>' for which no ahead of time (AOT) code was generated.

這可能是什么原因,我該如何解決?

對於我的具體情況(如果它對任何人有幫助)我正在使用

WrapperMethod<WeatherFrameInfo[]>();

WrapperMethod<T>() {
    JsonConvert.DeserializeObject<T>(json);
}

導致錯誤:

2022/03/17 14:53:32.888 13468 13524 Error Unity ExecutionEngineException: Attempting to call method 'System.Collections.Generic.List`1[[WeatherFrameInfo, ScriptsAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::.cctor' for which no ahead of time (AOT) code was generated.
2022/03/17 14:53:32.888 13468 13524 Error Unity   at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) [0x00000] in <00000000000000000000000000000000>:0 
2022/03/17 14:53:32.888 13468 13524 Error Unity   at Newtonsoft.Json.Utilities.LateBoundReflectionDelegateFactory+<>c__DisplayClass5_0`1[T].<CreateDefaultConstructor>b__1 () [0x00000] in <00000000000000000000000000000000>:0 
2022/03/17 14:53:32.888 13468 13524 Error Unity   at Newtonsoft.Json.Serialization.JsonArrayContract.CreateTemporaryCollection () [0x00000] in <00000000000000000000000000000000>:0 
2022/03/17 14:53:32.888 13468 13524 Error Unity   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewList (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonArrayContract contract, System.Boolean& createdFromNonDefaultCreator) [0x00000] in <00000000000000000000000000000000>:0 
2022/03/17 14:53:32.888 13468 13524 Error Unity   at Newtons

我推測Newtonsoft會在某個時候將我的數組輸入轉換為List ,所以我重構了我的代碼以提前完成此操作,violá

WrapperMethod<List<WeatherFrameInfo>>();

WrapperMethod<T>() {
    JsonConvert.DeserializeObject<T>(json);
}

好的,經過一些進一步的研究和測試,為什么會發生這種情況的結論如下:

由於根據方法是接口的一部分,並且只能通過接口或通過基礎 class 調用,因此從未通過此 class 顯式調用Example.TryGetValue方法。

由於Example class 與接口和基礎 class 位於不同的程序集中,因此Example.TryGetValue的代碼在編譯時以某種方式被剝離(因為編譯器認為它無論如何都不會使用),因此在構建的后期丟失。


我現在知道原因以及未來要考慮什么,但除了有一個明確的實現並調用它,它還不是一個真正的解決方案,所以它不會被剝奪......

要解決此類 AOT 問題,您可以強制編譯器生成正確的代碼。 您可以在 class 中添加以下示例方法:

public void UsedOnlyForAOTCodeGeneration() 
{
    // YOUR CODE HERE

    // Include an exception so we can be sure to know if this method is ever called.
    throw new InvalidOperationException("This method is used for AOT code generation only. 
    Do not call it at runtime.");
}

暫無
暫無

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

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