0

我有一个通用的方法来尝试使用我自己的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 和 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.

这可能是什么原因,我该如何解决?

4

2 回答 2

2

要解决此类 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.");
}
于 2020-06-09T14:38:51.100 回答
1

好的,经过一些进一步的研究和测试,为什么会发生这种情况的结论如下:

由于根据方法是接口的一部分,并且只能通过接口或基类调用,因此该Example.TryGetValue方法从未通过此类显式调用。

由于Example该类与接口和基类位于不同的程序集中,因此代码Example.TryGetValue在编译时以某种方式被剥离(因为编译器认为它永远不会被使用),因此在构建的后期丢失。


我现在知道未来的原因和要考虑的事情,但除了有一个明确的实现并调用它,它还不是一个真正的解决方案,所以它不会被剥夺......

于 2020-06-07T11:14:15.370 回答