Ändringar i reflektion anropar API-undantag

De undantag som kastas vid anrop av reflection-invoke-API:er har ändrats.

Tidigare beteende

Nytt beteende

Från och med .NET 7:

Version lanserad

.NET 7

Typ av brytande ändring

Den här ändringen kan påverka binär kompatibilitet.

Orsak till ändring

Om du kastar TargetInvocationException i stället för det ursprungliga undantaget blir upplevelsen mer konsekvent. Det ordnar korrekt undantag som orsakas av valideringen av inkommande parametrar (som inte är omslutna med TargetInvocationException) mot undantag som utlöses på grund av implementeringen av målmetoden (som är omslutna med TargetInvocationException). Konsekventa regler ger mer konsekventa upplevelser för olika implementeringar av CLR och API Invoke :er.

Ändringen att kasta NotSupportedException när en byref-liknande typ skickas till ett Invoke() API korrigerar ett misstag i den ursprungliga implementeringen, som inte kastade. Den ursprungliga implementeringen visade att ref struct typer stöds av API:erna Invoke() när de inte är det. Eftersom de aktuella Invoke() API:erna använder System.Object för parametertyper, och en ref struct typ inte kan boxas till System.Object, är det ett scenario som inte stöds.

Om du inte använder BindingFlags.DoNotWrapExceptions när du anropar Invoke()och du har catch instruktioner runt API:erna Invoke() för andra undantag än TargetInvocationExceptionkan du överväga att ändra eller ta bort dessa catch instruktioner. De andra undantagen kastas inte längre som ett resultat av anropet. Om du däremot fångar undantag från argumentvalidering som inträffar innan du försöker anropa målmetoden bör du behålla dessa catch instruktioner. Ogiltiga argument som valideras innan ett försök att anropa görs, kastas utan att omslutas med TargetInvocationException och har inte ändrat betydelse.

Överväg att använda BindingFlags.DoNotWrapExceptions så att TargetInvocationException aldrig kastas. I det här fallet kommer det ursprungliga undantaget inte att omslutas av en TargetInvocationException. I de flesta fall ökar chanserna att diagnostisera det faktiska problemet genom att inte omsluta undantaget, eftersom inte alla verktyg för undantagsrapportering visar det inre undantaget. Genom att använda BindingFlags.DoNotWrapExceptionsgenereras dessutom samma undantag som när metoden anropas direkt (utan reflektion). Detta är önskvärt i de flesta fall, eftersom valet av om reflektion används eller inte kan vara godtyckligt eller en implementeringsinformation som inte behöver dyka upp för anroparen.

I det sällsynta fallet att du behöver skicka ett standardvärde till en metod via reflektion som innehåller en byref-liknande parameter som skickas "efter värde" kan du lägga till en omslutningsmetod som utelämnar parametern och anropar målmetoden med ett standardvärde för parametern.

Berörda API:er