Maison >développement back-end >C++ >Pourquoi « Enumerable.Cast » lance-t-il une « InvalidCastException » lors de la diffusion à partir de « IEnumerable » ?

Pourquoi « Enumerable.Cast » lance-t-il une « InvalidCastException » lors de la diffusion à partir de « IEnumerable » ?

Patricia Arquette
Patricia Arquetteoriginal
2025-01-10 10:38:42695parcourir

Why Does `Enumerable.Cast` Throw an `InvalidCastException` When Casting from `IEnumerable`?

Exception de conversion déroutante dans Enumerable.Cast

Une InvalidCastException est rencontrée lors de la tentative de conversion d'un IEnumerable d'entiers (ints) en un IEnumerable de entiers longs (longs) en utilisant l'opérateur Cast, comme on le voit ci-dessous :

using System.Collections.Generic;
using System.Linq;

namespace InvalidCast
{
    class Program
    {
        static void Main(string[] args)
        {
            // Initialize a list of ints
            IEnumerable<int> list = new List<int>() { 1 };

            // Attempt to cast the list to longs
            IEnumerable<long> castedList = list.Cast<long>();

            // Attempt to write the first element of the casted list
            Console.WriteLine(castedList.First());
        }
    }
}

Pourquoi cette exception se produit-elle ?

Ce comportement est inattendu car l'opérateur Cast est destiné à effectuer une conversion sûre et fiable. Cependant, ce cas particulier démontre un problème particulier survenu lors d'une modification du comportement de Cast entre .NET 3.5 et .NET 3.5 SP1.

La racine du problème

L'opérateur Cast est une méthode d'extension définie pour IEnumerable (l'interface de base des collections), pas spécifiquement pour IEnumerable. Cela signifie que lorsque les valeurs sont converties, elles ont été encadrées dans des objets de type System.Object.

En conséquence, le processus de conversion imite ce qui suit :

int i = 1;
object o = i;
long l = (long)o;

Ce code lance l'InvalidCastException lorsqu'il tente de convertir un boxed int en un long, au lieu de lancer directement le int.

Solution de contournement

Pour résoudre ce problème, il est nécessaire d'effectuer le cast explicitement à l'aide d'une expression lambda ou d'une méthode de sélection, comme suit :

// Cast using a lambda expression
var castedList = list.Select(i => (long)i);

// Cast using a select method
var castedList = from long l in list select l;

Ces approches convertissent explicitement chaque valeur int en valeur longue, évitant ainsi le processus de boxing/unboxing et contournant le InvalidCastException.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn