Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A tükröződéshívási API-k meghívása során bevezetett kivételek megváltoztak.
Előző viselkedés
Amikor egy olyan meghívott metódus, amely értéket ad vissza hivatkozásként,
nullértéket adott vissza, NullReferenceException dobás történt korábban.A konstruktorok esetében a következő kivételek léptek fel:
- Átmeneti kivételek, beleértve a OutOfMemoryException.
- Amikor negatív OverflowException értéket adtunk át egy tömb hosszparaméteréhez.
Amikor
nullegy byref-szerű paraméterhez lett átadva arefmódosító nélkül (azaz érték szerint átadott), nem történt kivétel, és a futtatókörnyezet a null érték alapértelmezett értékét helyettesítte.
Új viselkedés
A .NET 7-től kezdve:
Ahelyett, hogy a kezdő kivételt dobják (beleértve NullReferenceException és OutOfMemoryException, ahogyan az a előző viselkedésben szerepel), TargetInvocationException kerül dobásra minden esetben, miután az kezdeti
Invoke()paraméterek ellenőrzésre kerültek. A belső kivétel tartalmazza a kiinduló kivételt.NotSupportedException akkor keletkezik, amikor
nullegy referencia-szerű paraméterként kerül átadásra, miközben a paraméter "érték szerint" (azaz nincsrefmódosító) van deklarálva. A kapcsolódó esetben, amikor a paramétert hivatkozással adják át (vagyis rendelkezik arefmódosítóval), az előző és az új viselkedés ugyanaz: NotSupportedException a van dobva.
Bevezetett verzió
.NET 7
A kompatibilitástörő változás típusa
Ez a változás befolyásolhatja a bináris kompatibilitást.
A változás oka
A kiinduló kivétel helyett a TargetInvocationException kivétel kezelése egységesebbé teszi a felhasználói élményt. Megfelelően rétegeli a bejövő paraméterek érvényesítéséből származó kivételeket (amelyek nincsenek beburkolva) szemben a célmetódus implementációja által kiváltott, beburkolt kivételekkel. A konzisztens szabályok konzisztensebb élményt nyújtanak a CLR és az API-k különböző implementációiban Invoke .
A változtatás, amely akkor lép életbe, amikor egy NotSupportedException API-hoz kerül átadásra, Invoke() kijavítja az eredeti implementáció figyelmetlenségét, amely nem dobott hibát. Az eredeti implementáció azt a látszatot keltette, hogy a ref struct típusokat támogatják a Invoke() API-k, pedig valójában nem így van. Mivel az aktuális Invoke() API-k System.Object paramétertípusok használatával működnek, és egy ref struct típus nem dobozolható System.Object típusra, ez nem támogatott szituáció.
Javasolt művelet
Ha nem használja a BindingFlags.DoNotWrapExceptions elemet a Invoke() hívásakor, és az catch utasítások az Invoke() API-k körül más kivételekre vonatkoznak, mint például a TargetInvocationException, fontolja meg ezeknek az catch utasításoknak a módosítását vagy eltávolítását. A többi kivételt a továbbiakban nem vetik ki a meghívás eredményeként. Ha azonban kivételeket észlel az argumentum-ellenőrzés alól, amely a célmetódus meghívása előtt történik, tartsa meg ezeket az catch utasításokat. Érvényesített érvénytelen argumentumok, amelyeket a rendszer a meghívás megkísérlése előtt dob ki anélkül, hogy TargetInvocationException-be burkolná őket, nem módosítják a szemantikát.
Fontolja meg a BindingFlags.DoNotWrapExceptions használatát, hogy a TargetInvocationException soha ne következzen be. Ebben az esetben a kiinduló kivételt nem fogja becsomagolni egy TargetInvocationException. A legtöbb esetben a kivétel körbefuttatásának elmaradása javítja a tényleges probléma diagnosztizálásának esélyét, mivel nem minden kivételjelentési eszköz jeleníti meg a belső kivételt. Emellett a BindingFlags.DoNotWrapExceptions használata során ugyanazok a kivételek jelentkeznek, mint amikor a metódust közvetlenül hívjuk meg (reflexió nélkül). Ez a legtöbb esetben kívánatos, mivel az a döntés, hogy a tükrözés használva van-e, vagy nem lehet tetszőleges, vagy olyan implementációs részlet, amelyet nem kell felszínre hoznunk a hívó számára.
Abban a ritka esetben, amikor az "érték szerint" átadott byref-szerű paramétert tartalmazó tükröződésen keresztül át kell adnia egy alapértelmezett értéket egy metódusnak, hozzáadhat egy burkolómetódust, amely kihagyja a paramétert, és meghívja a célmetódust az adott paraméter alapértelmezett értékével.
Érintett API-k
- System.Reflection.MethodBase.Invoke(Object, Object[])
- System.Reflection.MethodBase.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
- System.Reflection.ConstructorInfo.Invoke(Object[])
- System.Reflection.ConstructorInfo.Invoke(BindingFlags, Binder, Object[], CultureInfo)
- System.Reflection.PropertyInfo.GetValue(Object)
- System.Reflection.PropertyInfo.GetValue(Object, Object[])
- System.Reflection.PropertyInfo.GetValue(Object, BindingFlags, Binder, Object[], CultureInfo)
- System.Reflection.PropertyInfo.SetValue(Object, Object)
- System.Reflection.PropertyInfo.SetValue(Object, Object, Object[])
- System.Reflection.PropertyInfo.SetValue(Object, Object, BindingFlags, Binder, Object[], CultureInfo)
- System.Reflection.Emit.DynamicMethod.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
- System.Activator.CreateInstance(Type, Object[])
- System.Activator.CreateInstance(Type, Object[], Object[])
- System.Activator.CreateInstance(Type, BindingFlags, Binder, Object[], CultureInfo)
- System.Activator.CreateInstance(Type, BindingFlags, Binder, Object[], CultureInfo, Object[])
- System.Activator.CreateInstance(String, String, Boolean, BindingFlags, Binder, Object[], CultureInfo, Object[])