Maison >développement back-end >C++ >Pourquoi `IEnumerable.Cast()` lance-t-il une `InvalidCastException` dans .NET 3.5 SP1 ?
Découvrez le mystère du Enumerable.Cast()
jetéInvalidCastException
Dans .NET 3.5 SP1, une exception Cast<T>()
a été levée de manière déroutante lors de la conversion de IEnumerable
à l'aide de InvalidCastException
. Considérez le code suivant :
<code class="language-csharp">IEnumerable<int> list = new List<int>() { 1 }; IEnumerable<long> castedList = list.Cast<long>(); Console.WriteLine(castedList.First());</code>
Pourquoi ce code lève-t-il une exception ?
Ce comportement inhabituel provient de changements dans le comportement de la méthode Cast<T>()
entre .NET 3.5 et .NET 3.5 SP1. Avant le SP1, Cast<T>()
agissait sur IEnumerable<T>
, permettant une conversion directe. Cependant, dans le SP1, il a été modifié pour fonctionner sur IEnumerable
, ce qui signifie que l'élément est déballé en System.Object
avant d'être converti.
Cette opération de déballage entraîne InvalidCastException
car contrairement à la conversion de int
directement en long
, la conversion d'un int
en boîte en long
n'est pas autorisée. En fait, ce code tente d'effectuer les opérations suivantes :
<code class="language-csharp">int i = 1; object o = i; long l = (long)o;</code>
Cela entraînera également le même InvalidCastException
.
Solutions et explications
Pour résoudre ce problème, vous pouvez utiliser des expressions lambda pour convertir explicitement les éléments :
<code class="language-csharp">var castedList = list.Select(i => (long)i);</code>
Cela convertira avec succès l'élément en long
.
est que Cast<T>()
est une méthode d'extension de IEnumerable
, pas de IEnumerable<T>
. Lorsque les éléments atteignent l’étape de transformation, ils ont déjà été encadrés comme object
. Cela entraîne object
lors de la conversion de InvalidCastException
vers un type spécifique.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!