Ich bin verwirrt über einige Reflection-Code und der Suche nach Einsicht
-
19-09-2019 - |
Frage
Ich entwickle für das iPhone mit C # und Full AOT-Technologie Mono. Nach ihrem Einschränkungen Seite ( Link-Text ), im Gegensatz zu herkömmlicher Mono /. NET, Code auf dem iPhone ist statisch vor der Zeit kompiliert statt auf Anforderung durch einen JIT-Compiler kompiliert werden.
Wenn auf der Hardware läuft, wird die folgende Ausnahme auftritt:
ExecutionEngineException: Attempting to JIT compile method 'System.Reflection.MonoProperty:GetterAdapterFrame<Image, UnityEngine.Color> (System.Reflection.MonoProperty/Getter`2<Image, UnityEngine.Color>,object)' while running with --aot-only.
System.Reflection.MonoProperty.GetValue (System.Object obj, System.Object[] index) [0x00000]
Ani+AniValue.Get ()
Ani.CreateAnimations (System.Object obj, System.Collections.Hashtable properties, Single duration, System.Collections.Hashtable options, AniType type)
Ani.Method (AniType type, System.Object obj, Single duration, System.Collections.Hashtable _properties, System.Collections.Hashtable _options)
Ani.From (System.Object obj, Single duration, System.Collections.Hashtable _properties)
xObject+<>c__CompilerGenerated5.MoveNext ()
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
xObject:StartAnimation(Animate, GameObject, Object, Object)
SceneSplash:CreateBackground()
SceneSplash:OnSetup()
SceneSplash:OnSceneActivate(Callback)
GameController:ActivateScene()
GameController:DeactivateScene()
GameController:SceneLoaded(Scene, GameObject, SceneBase)
SceneBase:Start()
Gemäß dem Dokument Einschränkungen ist System.Reflection.Emit nicht unterstützt, aber sie sagen, dass als Seiten von Reflection.Emit „die gesamten Reflexion API, einschließlich Type.GetType (“ someclass "), Auflisten Methoden, Liste Immobilien , Abrufen von Attributen und Werte funktionieren gut. "
Ich habe den Code enthalten, der die Ausnahme verursacht ...
void CreateAnimations(System.Object obj, Hashtable properties, float duration,
Hashtable options, AniType type)
{
foreach (DictionaryEntry item in properties)
{
name = (string)item.Key; // Extract name and value
System.Object value = item.Value;
AniValue foo = new AniValue(obj, name); // Create value object
/* To exception occurs inside Get() */
System.Object current = foo.Get(); // Get current value
...
Das obige Verfahren packt einen Eigenschaftsnamen von einer Hash-Tabelle, und verwendet sie (zusammen mit obj) eine Instanz von AniValue zu erstellen. Genau danach foo.Get () aufgerufen, um den Wert der Eigenschaft abzurufen. Die Ausnahme tritt auf propertyInfo.GetValue (obj, null).
using System.Reflection
public class AniValue
{
static BindingFlags bFlags = BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.Static;
System.Object obj; // Object a field or property is animated on
string name; // Name of the field or property
System.Type objType; // Type object
FieldInfo fieldInfo; // FieldInfo object
PropertyInfo propertyInfo; // PropertyInfo object
public AniValue(System.Object o, string n)
{
obj = o;
name = n;
objType = obj.GetType();
fieldInfo = objType.GetField(n, AniValue.bFlags);
propertyInfo = objType.GetProperty(n, AniValue.bFlags);
if (fieldInfo == null && propertyInfo == null)
{
throw new System.MissingMethodException("Property or field '" + n
+ "' not found on " + obj);
}
}
// Get field or property
public System.Object Get()
{
if (propertyInfo != null)
{
/* The next line causes the Exception */
return propertyInfo.GetValue(obj, null);
}
else
{
return fieldInfo.GetValue(obj);
}
}
...
Obwohl ich habe Erfahrung mit C # begrenzt, JIT, AOT und Reflexion, sollte GetValue () Trigger JIT? UnityEngine.Color ist eine Struktur, und die Image-Klasse ist als Unterklasse von XObject, die eine Unterklasse von UnityEngine.MonoBehaviour ist. Farbe ist eine Eigenschaft Bild, und das ist, was der Code den Wert des Erhaltens werden könnte, wenn die Ausnahme auftritt.
Interessanterweise können Sie den Code kompilieren feines .NET 1.1, und alles führt werden. Nur wenn kompilieren Sie .NET 2.1 ist die Ausnahme auftreten werden.
Ich weiß nicht, ob es eine Lösung gibt oder arbeiten um zu dieser, aber ich würde auf jeden Einblick über die Ursache interessiert sein.
Lösung
IIRC, gibt es auch eine Warnung über Generika durch Reflexion. I glauben es Schnittstellen ruft statt konkreten Typen, aber die gleiche Gebühr -. In insbesondere , wenn Reflexion mit
Ich persönlich bin nur Reflexion fallen, wenn mit dem iPhone zu tun - es ist einfacher. Ich mache immer noch Meta-Programmierung, aber ich bin Pre-Generierung regulären Code (auf dem vollen Rahmen), die ich übernehme dann zu Monotouch. Es scheint ziemlich robust zu arbeiten.