Проблема с AOT (заблаговременно) в общем методе c после сборки в UWP и Il2CPP - PullRequest
0 голосов
/ 28 мая 2020

У меня есть общий c метод для попытки получить общее c значение из словаря с помощью ключа, используя мой собственный 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, но как только это будет построено для UWP и IL2 CPP, как только я попытаюсь запустить метод, например,

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.

В чем может быть причина и как это исправить?

Ответы [ 2 ]

1 голос
/ 07 июня 2020

Хорошо, после некоторых дальнейших исследований и тестов вывод о том, почему это произошло, выглядит следующим образом:

Поскольку соответствующий метод был частью интерфейса и вызывается только через интерфейс или через базовый класс, метод Example.TryGetValue никогда явно не вызывался через этот класс.

Поскольку класс Example живет в другой сборке, чем интерфейс и базовый класс, код для Example.TryGetValue каким-то образом был удален во время компиляции (поскольку компилятор считает это в любом случае никогда не используется) и поэтому отсутствует позже в сборке.


Теперь я знаю причину и то, что нужно иметь в виду на будущее, но еще не реальное решение, кроме наличия явной реализации и вызова этого чтобы не лишился ...

0 голосов
/ 09 июня 2020

Чтобы обойти проблему AOT, подобную этой, вы можете заставить компилятор сгенерировать правильный код. Вы можете добавить в свой класс следующий пример метода:

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.");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...