InvalidOperationException Classe

Définition

Exception levée en cas d'appel de méthode non valide pour l'état actuel de l'objet.The exception that is thrown when a method call is invalid for the object's current state.

public ref class InvalidOperationException : SystemException
[System.Runtime.InteropServices.ComVisible(true)]
[System.Serializable]
public class InvalidOperationException : SystemException
type InvalidOperationException = class
    inherit SystemException
Public Class InvalidOperationException
Inherits SystemException
Héritage
InvalidOperationException
Dérivé
Attributs

Remarques

InvalidOperationException est utilisé dans les cas où l’échec de l’appel d’une méthode est dû à des raisons autres que des arguments non valides.InvalidOperationException is used in cases when the failure to invoke a method is caused by reasons other than invalid arguments. En général, elle est levée lorsque l’état d’un objet ne peut pas prendre en charge l’appel de méthode.Typically, it is thrown when the state of an object cannot support the method call. Par exemple, une exception InvalidOperationException est levée par des méthodes telles que :For example, an InvalidOperationException exception is thrown by methods such as:

  • IEnumerator.MoveNext si les objets d’une collection sont modifiés après la création de l’énumérateur.IEnumerator.MoveNext if objects of a collection are modified after the enumerator is created. Pour plus d’informations, consultez modification d’une collection lorsde l’itération.For more information, see Changing a collection while iterating it.

  • ResourceSet.GetString si l’ensemble de ressources est fermé avant l’appel de la méthode.ResourceSet.GetString if the resource set is closed before the method call is made.

  • XContainer.Add, si l’objet ou les objets à ajouter entraînent un document XML mal structuré.XContainer.Add, if the object or objects to be added would result in an incorrectly structured XML document.

  • Méthode qui tente de manipuler l’interface utilisateur à partir d’un thread qui n’est pas le thread principal ou le thread d’interface utilisateur.A method that attempts to manipulate the UI from a thread that is not the main or UI thread.

Important

Étant donné que l’exception InvalidOperationException peut être levée dans une grande variété de circonstances, il est important de lire le message d’exception retourné par la propriété Message.Because the InvalidOperationException exception can be thrown in a wide variety of circumstances, it is important to read the exception message returned by the Message property.

Dans cette section :In this section:

Causes courantes des exceptions InvalidOperationException Some common causes of InvalidOperationException exceptions
Mise à jour d’un thread d’interface utilisateur à partir d’un thread autre qu’un thread d’interface utilisateurUpdating a UI thread from a non-UI thread
Modification d’une collection lors de son itérationChanging a collection while iterating it
Tri d’un tableau ou d’une collection dont les objets ne peuvent pas être comparésSorting an array or collection whose objects cannot be compared
Le cast d’un<t Nullable> null en son type sous-jacent Casting a Nullable<T> that is null to its underlying type
Appel d’une méthode System. Linq. Enumerable sur une collection videCalling a System.Linq.Enumerable method on an empty collection
Appel de Enumerable. Single ou Enumerable. SingleOrDefault sur une séquence sans élémentCalling Enumerable.Single or Enumerable.SingleOrDefault on a sequence without one element
Accès au champ de domaine d’application croisé dynamiqueDynamic cross-application domain field access
Levée d’une exception InvalidOperationExceptionThrowing an InvalidOperationException exception
Informations diversesMiscellaneous information

Causes courantes des exceptions InvalidOperationExceptionSome common causes of InvalidOperationException exceptions

Les sections suivantes montrent comment des cas courants dans lesquels, dans InvalidOperationException exception, sont levées dans une application.The following sections show how some common cases in which in InvalidOperationException exception is thrown in an app. La façon dont vous gérez le problème dépend de la situation spécifique.How you handle the issue depends on the specific situation. Toutefois, le plus souvent, l’exception résulte de l’erreur du développeur, et l’exception InvalidOperationException peut être anticipée et évitée.Most commonly, however, the exception results from developer error, and the InvalidOperationException exception can be anticipated and avoided.

Mise à jour d’un thread d’interface utilisateur à partir d’un thread autre qu’un thread d’interface utilisateurUpdating a UI thread from a non-UI thread

Souvent, les threads de travail sont utilisés pour effectuer des tâches en arrière-plan qui impliquent la collecte de données à afficher dans l’interface utilisateur d’une application.Often, worker threads are used to perform some background work that involves gathering data to be displayed in an application's user interface. Toutefois.However. la plupart des infrastructures d’application de l’interface graphique utilisateur pour le .NET Framework, telles que Windows Forms et Windows Presentation Foundation (WPF), vous permettent d’accéder aux objets GUI uniquement à partir du thread qui crée et gère l’interface utilisateur (le thread principal ou le thread d’interface utilisateur).most GUI (graphical user interface) application frameworks for the .NET Framework, such as Windows Forms and Windows Presentation Foundation (WPF), let you access GUI objects only from the thread that creates and manages the UI (the Main or UI thread). Une InvalidOperationException est levée lorsque vous essayez d’accéder à un élément d’interface utilisateur à partir d’un thread autre que le thread d’interface utilisateur.An InvalidOperationException is thrown when you try to access a UI element from a thread other than the UI thread. Le texte du message d’exception est indiqué dans le tableau suivant.The text of the exception message is shown in the following table.

Type d'applicationApplication Type MessageMessage
Application WPFWPF app Le thread appelant ne peut pas accéder à cet objet parce qu’un autre thread en est propriétaire.The calling thread cannot access this object because a different thread owns it.
Application UWPUWP app L’application a appelé une interface qui a été marshalée pour un thread différent.The application called an interface that was marshaled for a different thread.
Application Windows FormsWindows Forms app Opération inter-threads non valide : le contrôle’TextBox1 'est accessible à partir d’un thread autre que le thread sur lequel il a été créé.Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on.

Les infrastructures d’interface utilisateur pour le .NET Framework implémentent un modèle de répartiteur qui comprend une méthode pour vérifier si un appel à un membre d’un élément d’interface utilisateur est en cours d’exécution sur le thread d’interface utilisateur et d’autres méthodes pour planifier l’appel sur le thread d’interface utilisateur :UI frameworks for the .NET Framework implement a dispatcher pattern that includes a method to check whether a call to a member of a UI element is being executed on the UI thread, and other methods to schedule the call on the UI thread:

  • Dans les applications WPF, appelez la méthode Dispatcher.CheckAccess pour déterminer si une méthode est en cours d’exécution sur un thread autre qu’un thread d’interface utilisateur.In WPF apps, call the Dispatcher.CheckAccess method to determine if a method is running on a non-UI thread. Elle retourne true si la méthode s’exécute sur le thread d’interface utilisateur et false dans le cas contraire.It returns true if the method is running on the UI thread and false otherwise. Appelez l’une des surcharges de la méthode Dispatcher.Invoke pour planifier l’appel sur le thread d’interface utilisateur.Call one of the overloads of the Dispatcher.Invoke method to schedule the call on the UI thread.

  • Dans les applications UWP, vérifiez la propriété CoreDispatcher.HasThreadAccess pour déterminer si une méthode est en cours d’exécution sur un thread autre qu’un thread d’interface utilisateur.In UWP apps, check the CoreDispatcher.HasThreadAccess property to determine if a method is running on a non-UI thread. Appelez la méthode CoreDispatcher.RunAsync pour exécuter un délégué qui met à jour le thread d’interface utilisateur.Call the CoreDispatcher.RunAsync method to execute a delegate that updates the UI thread.

  • Dans Windows Forms applications, utilisez la propriété Control.InvokeRequired pour déterminer si une méthode s’exécute sur un thread non-interface utilisateur.In Windows Forms apps, use the Control.InvokeRequired property to determine if a method is running on a non-UI thread. Appelez l’une des surcharges de la méthode Control.Invoke pour exécuter un délégué qui met à jour le thread d’interface utilisateur.Call one of the overloads of the Control.Invoke method to execute a delegate that updates the UI thread.

Les exemples suivants illustrent la InvalidOperationException exception qui est levée lorsque vous tentez de mettre à jour un élément d’interface utilisateur à partir d’un thread autre que le thread qui l’a créé.The following examples illustrate the InvalidOperationException exception that is thrown when you attempt to update a UI element from a thread other than the thread that created it. Chaque exemple requiert la création de deux contrôles :Each example requires that you create two controls:

  • Contrôle de zone de texte nommé textBox1.A text box control named textBox1. Dans une application Windows Forms, vous devez définir sa propriété Multiline sur true.In a Windows Forms app, you should set its Multiline property to true.

  • Contrôle Button nommé threadExampleBtn.A button control named threadExampleBtn. L’exemple fournit un gestionnaire, ThreadsExampleBtn_Click, pour l’événement Click du bouton.The example provides a handler, ThreadsExampleBtn_Click, for the button's Click event.

Dans chaque cas, le gestionnaire d’événements threadExampleBtn_Click appelle deux fois la méthode DoSomeWork.In each case, the threadExampleBtn_Click event handler calls the DoSomeWork method twice. Le premier appel s’exécute de façon synchrone et fonctionne.The first call runs synchronously and succeeds. Mais le deuxième appel, parce qu’il s’exécute de façon asynchrone sur un thread de pool de threads, tente de mettre à jour l’interface utilisateur à partir d’un thread qui n’est pas une interface utilisateur.But the second call, because it runs asynchronously on a thread pool thread, attempts to update the UI from a non-UI thread. Il en résulte une exception InvalidOperationException.This results in a InvalidOperationException exception.

Applications WPF et UWPWPF and UWP apps

private async void threadExampleBtn_Click(object sender, RoutedEventArgs e)
{
    textBox1.Text = String.Empty;

    textBox1.Text = "Simulating work on UI thread.\n";
    DoSomeWork(20);
    textBox1.Text += "Work completed...\n";

    textBox1.Text += "Simulating work on non-UI thread.\n";
    await Task.Run( () => DoSomeWork(1000));
    textBox1.Text += "Work completed...\n";
}

private async void DoSomeWork(int milliseconds)
{
    // Simulate work.
    await Task.Delay(milliseconds);

    // Report completion.
    var msg = String.Format("Some work completed in {0} ms.\n", milliseconds);
    textBox1.Text += msg;
}
Private Async Sub threadExampleBtn_Click(sender As Object, e As RoutedEventArgs) Handles threadExampleBtn.Click
    textBox1.Text = String.Empty

    textBox1.Text = "Simulating work on UI thread." + vbCrLf
    DoSomeWork(20)
    textBox1.Text += "Work completed..." + vbCrLf

    textBox1.Text += "Simulating work on non-UI thread." + vbCrLf
    Await Task.Factory.StartNew(Sub()
                                    DoSomeWork(1000)
                                End Sub)
    textBox1.Text += "Work completed..." + vbCrLf
End Sub

Private Async Sub DoSomeWork(milliseconds As Integer)
    ' Simulate work.
    Await Task.Delay(milliseconds)

    ' Report completion.
    Dim msg = String.Format("Some work completed in {0} ms.", milliseconds) + vbCrLf
    textBox1.Text += msg
End Sub

La version suivante de la méthode DoSomeWork élimine l’exception dans une application WPF.The following version of the DoSomeWork method eliminates the exception in a WPF app.

private async void DoSomeWork(int milliseconds)
{
    // Simulate work.
    await Task.Delay(milliseconds);

    // Report completion.
    bool uiAccess = textBox1.Dispatcher.CheckAccess();
    String msg = String.Format("Some work completed in {0} ms. on {1}UI thread\n",
                               milliseconds, uiAccess ? String.Empty : "non-");
    if (uiAccess)
        textBox1.Text += msg;
    else
        textBox1.Dispatcher.Invoke(() => { textBox1.Text += msg; });
}
Private Async Sub DoSomeWork(milliseconds As Integer)
    ' Simulate work.
    Await Task.Delay(milliseconds)

    ' Report completion.
    Dim uiAccess As Boolean = textBox1.Dispatcher.CheckAccess()
    Dim msg As String = String.Format("Some work completed in {0} ms. on {1}UI thread",
                                      milliseconds, If(uiAccess, String.Empty, "non-")) + 
                                      vbCrLf 
    If uiAccess Then
        textBox1.Text += msg
    Else
        textBox1.Dispatcher.Invoke( Sub() textBox1.Text += msg)
    End If
End Sub

La version suivante de la méthode DoSomeWork élimine l’exception dans une application UWP.The following version of the DoSomeWork method eliminates the exception in a UWP app.

private async void DoSomeWork(int milliseconds)
{
    // Simulate work.
    await Task.Delay(milliseconds);

    // Report completion.
    bool uiAccess = textBox1.Dispatcher.HasThreadAccess;
    String msg = String.Format("Some work completed in {0} ms. on {1}UI thread\n",
                               milliseconds, uiAccess ? String.Empty : "non-");
    if (uiAccess)
        textBox1.Text += msg;
    else
        await textBox1.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { textBox1.Text += msg; });
}
Private Async Sub DoSomeWork(milliseconds As Integer)
    ' Simulate work.
    Await Task.Delay(milliseconds)

    ' Report completion.
    Dim uiAccess As Boolean = textBox1.Dispatcher.HasThreadAccess
    Dim msg As String = String.Format("Some work completed in {0} ms. on {1}UI thread" + vbCrLf,
                                      milliseconds, If(uiAccess, String.Empty, "non-"))
    If (uiAccess) Then
        textBox1.Text += msg
    Else
        Await textBox1.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub() textBox1.Text += msg)
    End If
End Sub

Applications Windows FormsWindows Forms apps

List<String> lines = new List<String>();

private async void threadExampleBtn_Click(object sender, EventArgs e)
{
    textBox1.Text = String.Empty;
    lines.Clear();

    lines.Add("Simulating work on UI thread.");
    textBox1.Lines = lines.ToArray();
    DoSomeWork(20);

    lines.Add("Simulating work on non-UI thread.");
    textBox1.Lines = lines.ToArray();
    await Task.Run(() => DoSomeWork(1000));

    lines.Add("ThreadsExampleBtn_Click completes. ");
    textBox1.Lines = lines.ToArray();
}

private async void DoSomeWork(int milliseconds)
{
    // simulate work
    await Task.Delay(milliseconds);

    // report completion
    lines.Add(String.Format("Some work completed in {0} ms on UI thread.", milliseconds));
    textBox1.Lines = lines.ToArray();
}
Dim lines As New List(Of String)()
Private Async Sub threadExampleBtn_Click(sender As Object, e As EventArgs) Handles threadExampleBtn.Click
    textBox1.Text = String.Empty
    lines.Clear()

    lines.Add("Simulating work on UI thread.")
    textBox1.Lines = lines.ToArray()
    DoSomeWork(20)

    lines.Add("Simulating work on non-UI thread.")
    textBox1.Lines = lines.ToArray()
    Await Task.Run(Sub() DoSomeWork(1000))

    lines.Add("ThreadsExampleBtn_Click completes. ")
    textBox1.Lines = lines.ToArray()
End Sub

Private Async Sub DoSomeWork(milliseconds As Integer)
    ' Simulate work.
    Await Task.Delay(milliseconds)

    ' Report completion.
    lines.Add(String.Format("Some work completed in {0} ms on UI thread.", milliseconds))
    textBox1.Lines = lines.ToArray()
End Sub

La version suivante de la méthode DoSomeWork élimine l’exception dans une application Windows Forms.The following version of the DoSomeWork method eliminates the exception in a Windows Forms app.

private async void DoSomeWork(int milliseconds)
{
    // simulate work
    await Task.Delay(milliseconds);

    // Report completion.
    bool uiMarshal = textBox1.InvokeRequired;
    String msg = String.Format("Some work completed in {0} ms. on {1}UI thread\n",
                               milliseconds, uiMarshal ? String.Empty : "non-");
    lines.Add(msg);

    if (uiMarshal) {
        textBox1.Invoke(new Action(() => { textBox1.Lines = lines.ToArray(); }));
    }
    else {
        textBox1.Lines = lines.ToArray();
    }
}
Private Async Sub DoSomeWork(milliseconds As Integer)
    ' Simulate work.
    Await Task.Delay(milliseconds)

    ' Report completion.
    Dim uiMarshal As Boolean = textBox1.InvokeRequired
    Dim msg As String = String.Format("Some work completed in {0} ms. on {1}UI thread" + vbCrLf,
                                      milliseconds, If(uiMarshal, String.Empty, "non-"))
    lines.Add(msg)

    If uiMarshal Then
        textBox1.Invoke(New Action(Sub() textBox1.Lines = lines.ToArray()))
    Else
        textBox1.Lines = lines.ToArray()
    End If
End Sub

Modification d’une collection lors de son itérationChanging a collection while iterating it

L’instruction foreach dans C# une instruction ou For Each dans Visual Basic est utilisée pour itérer les membres d’une collection et lire ou modifier ses éléments individuels.The foreach statement in C# or For Each statement in Visual Basic is used to iterate the members of a collection and to read or modify its individual elements. Toutefois, il ne peut pas être utilisé pour ajouter ou supprimer des éléments dans la collection.However, it can't be used to add or remove items from the collection. Cela lève une exception InvalidOperationException avec un message semblable au suivant : «la**collection a été modifiée ; l’opération d’énumération ne peut pas s’exécuter.**»Doing this throws an InvalidOperationException exception with a message that is similar to, "Collection was modified; enumeration operation may not execute."

L’exemple suivant itère une collection d’entiers qui tente d’ajouter le carré de chaque entier à la collection.The following example iterates a collection of integers attempts to add the square of each integer to the collection. L’exemple lève une InvalidOperationException avec le premier appel à la méthode List<T>.Add.The example throws an InvalidOperationException with the first call to the List<T>.Add method.

using System;
using System.Collections.Generic;

public class Example
{
   public static void Main()
   {
      var numbers = new List<int>() { 1, 2, 3, 4, 5 };
      foreach (var number in numbers) {
         int square = (int) Math.Pow(number, 2);
         Console.WriteLine("{0}^{1}", number, square);
         Console.WriteLine("Adding {0} to the collection...\n", square);
         numbers.Add(square);
      }
   }
}
// The example displays the following output:
//    1^1
//    Adding 1 to the collection...
//    
//    
//    Unhandled Exception: System.InvalidOperationException: Collection was modified; 
//       enumeration operation may not execute.
//       at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
//       at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
//       at Example.Main()
Imports System.Collections.Generic

Module Example
   Public Sub Main()
      Dim numbers As New List(Of Integer)( { 1, 2, 3, 4, 5 } )
      For Each number In numbers
         Dim square As Integer = CInt(Math.Pow(number, 2))
         Console.WriteLine("{0}^{1}", number, square)
         Console.WriteLine("Adding {0} to the collection..." + vbCrLf, 
                           square)
         numbers.Add(square)
      Next
   End Sub
End Module
' The example displays the following output:
'    1^1
'    Adding 1 to the collection...
'    
'    
'    Unhandled Exception: System.InvalidOperationException: Collection was modified; 
'       enumeration operation may not execute.
'       at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
'       at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
'       at Example.Main()

Vous pouvez éliminer l’exception de l’une des deux façons suivantes, en fonction de votre logique d’application :You can eliminate the exception in one of two ways, depending on your application logic:

  • Si les éléments doivent être ajoutés à la collection lors de l’itération, vous pouvez les itérer par index à l’aide de l’instruction for au lieu de foreach ou For Each.If elements must be added to the collection while iterating it, you can iterate it by index using the for statement instead of foreach or For Each. L’exemple suivant utilise l’instruction for pour ajouter le carré des nombres de la collection à la collection.The following example uses the for statement to add the square of numbers in the collection to the collection.

    using System;
    using System.Collections.Generic;
    
    public class Example
    {
       public static void Main()
       {
          var numbers = new List<int>() { 1, 2, 3, 4, 5 };
          
          int upperBound = numbers.Count - 1;
          for (int ctr = 0; ctr <= upperBound; ctr++) {
             int square = (int) Math.Pow(numbers[ctr], 2);
             Console.WriteLine("{0}^{1}", numbers[ctr], square);
             Console.WriteLine("Adding {0} to the collection...\n", square);
             numbers.Add(square);
          }
       
          Console.WriteLine("Elements now in the collection: ");
          foreach (var number in numbers)
             Console.Write("{0}    ", number);
       }
    }
    // The example displays the following output:
    //    1^1
    //    Adding 1 to the collection...
    //    
    //    2^4
    //    Adding 4 to the collection...
    //    
    //    3^9
    //    Adding 9 to the collection...
    //    
    //    4^16
    //    Adding 16 to the collection...
    //    
    //    5^25
    //    Adding 25 to the collection...
    //    
    //    Elements now in the collection:
    //    1    2    3    4    5    1    4    9    16    25
    
    Imports System.Collections.Generic
    
    Module Example
       Public Sub Main()
          Dim numbers As New List(Of Integer)( { 1, 2, 3, 4, 5 } )
          Dim upperBound = numbers.Count - 1
    
          For ctr As Integer = 0 To upperBound
             Dim square As Integer = CInt(Math.Pow(numbers(ctr), 2))
             Console.WriteLine("{0}^{1}", numbers(ctr), square)
             Console.WriteLine("Adding {0} to the collection..." + vbCrLf, 
                               square)
             numbers.Add(square)
          Next
       
          Console.WriteLine("Elements now in the collection: ")
          For Each number In numbers
             Console.Write("{0}    ", number)
          Next   
       End Sub
    End Module
    ' The example displays the following output:
    '    1^1
    '    Adding 1 to the collection...
    '    
    '    2^4
    '    Adding 4 to the collection...
    '    
    '    3^9
    '    Adding 9 to the collection...
    '    
    '    4^16
    '    Adding 16 to the collection...
    '    
    '    5^25
    '    Adding 25 to the collection...
    '    
    '    Elements now in the collection:
    '    1    2    3    4    5    1    4    9    16    25
    

    Notez que vous devez établir le nombre d’itérations avant d’effectuer l’itération de la collection en utilisant un compteur à l’intérieur de la boucle qui quittera la boucle de manière appropriée, en effectuant une itération vers l’arrière, de Count-1 à 0, ou, comme le fait l’exemple, en assignant le nombre d’éléments dans le tableau à une variable et en l’utilisant pourNote that you must establish the number of iterations before iterating the collection either by using a counter inside the loop that will exit the loop appropriately, by iterating backward, from Count - 1 to 0, or, as the example does, by assigning the number of elements in the array to a variable and using it to establish the upper bound of the loop. Sinon, si un élément est ajouté à la collection à chaque itération, une boucle sans fin est générée.Otherwise, if an element is added to the collection on every iteration, an endless loop results.

  • S’il n’est pas nécessaire d’ajouter des éléments à la collection lors de l’itération, vous pouvez stocker les éléments à ajouter dans une collection temporaire que vous ajoutez lorsque l’itération de la collection est terminée.If it is not necessary to add elements to the collection while iterating it, you can store the elements to be added in a temporary collection that you add when iterating the collection has finished. L’exemple suivant utilise cette approche pour ajouter le carré des nombres d’une collection à une collection temporaire, puis pour combiner les collections en un objet de tableau unique.The following example uses this approach to add the square of numbers in a collection to a temporary collection, and then to combine the collections into a single array object.

    using System;
    using System.Collections.Generic;
    
    public class Example
    {
       public static void Main()
       {
          var numbers = new List<int>() { 1, 2, 3, 4, 5 };
          var temp = new List<int>();
          
          // Square each number and store it in a temporary collection.
          foreach (var number in numbers) {
             int square = (int) Math.Pow(number, 2);
             temp.Add(square);
          }
        
          // Combine the numbers into a single array.
          int[] combined = new int[numbers.Count + temp.Count];
          Array.Copy(numbers.ToArray(), 0, combined, 0, numbers.Count);
          Array.Copy(temp.ToArray(), 0, combined, numbers.Count, temp.Count);
          
          // Iterate the array.
          foreach (var value in combined)
             Console.Write("{0}    ", value);
       }
    }
    // The example displays the following output:
    //       1    2    3    4    5    1    4    9    16    25
    
    Imports System.Collections.Generic
    
    Module Example
       Public Sub Main()
          Dim numbers As New List(Of Integer)( { 1, 2, 3, 4, 5 } )
          Dim temp As New List(Of Integer)()
          
          ' Square each number and store it in a temporary collection.
          For Each number In numbers
             Dim square As Integer = CInt(Math.Pow(number, 2))
             temp.Add(square)
          Next
        
          ' Combine the numbers into a single array.
          Dim combined(numbers.Count + temp.Count - 1) As Integer 
          Array.Copy(numbers.ToArray(), 0, combined, 0, numbers.Count)
          Array.Copy(temp.ToArray(), 0, combined, numbers.Count, temp.Count)
          
          ' Iterate the array.
          For Each value In combined
             Console.Write("{0}    ", value)
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '       1    2    3    4    5    1    4    9    16    25
    

Tri d’un tableau ou d’une collection dont les objets ne peuvent pas être comparésSorting an array or collection whose objects cannot be compared

Les méthodes de tri à usage général, telles que la méthode Array.Sort(Array) ou la méthode List<T>.Sort(), requièrent généralement qu’au moins un des objets à trier implémente l' IComparable<T> ou l’interface IComparable.General-purpose sorting methods, such as the Array.Sort(Array) method or the List<T>.Sort() method, usually require that at least one of the objects to be sorted implement the IComparable<T> or the IComparable interface. Si ce n’est pas le cas, la collection ou le tableau ne peut pas être trié, et la méthode lève une exception InvalidOperationException.If not, the collection or array cannot be sorted, and the method throws an InvalidOperationException exception. L’exemple suivant définit une classe Person, stocke deux objets Person dans un objet List<T> générique et tente de les trier.The following example defines a Person class, stores two Person objects in a generic List<T> object, and attempts to sort them. Comme le montre la sortie de l’exemple, l’appel à la méthode List<T>.Sort() lève une InvalidOperationException.As the output from the example shows, the call to the List<T>.Sort() method throws an InvalidOperationException.

using System;
using System.Collections.Generic;

public class Person
{
   public Person(String fName, String lName)
   {
      FirstName = fName;
      LastName = lName;
   }
   
   public String FirstName { get; set; }
   public String LastName { get; set; }
}

public class Example
{
   public static void Main()
   {
      var people = new List<Person>();
      
      people.Add(new Person("John", "Doe"));
      people.Add(new Person("Jane", "Doe"));
      people.Sort();
      foreach (var person in people)
         Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
   }
}
// The example displays the following output:
//    Unhandled Exception: System.InvalidOperationException: Failed to compare two elements in the array. ---> 
//       System.ArgumentException: At least one object must implement IComparable.
//       at System.Collections.Comparer.Compare(Object a, Object b)
//       at System.Collections.Generic.ArraySortHelper`1.SwapIfGreater(T[] keys, IComparer`1 comparer, Int32 a, Int32 b)
//       at System.Collections.Generic.ArraySortHelper`1.DepthLimitedQuickSort(T[] keys, Int32 left, Int32 right, IComparer`1 comparer, Int32 depthLimit)
//       at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
//       --- End of inner exception stack trace ---
//       at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
//       at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
//       at System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer)
//       at Example.Main()
Imports System.Collections.Generic

Public Class Person
   Public Sub New(fName As String, lName As String)
      FirstName = fName
      LastName = lName
   End Sub
   
   Public Property FirstName As String
   Public Property LastName As String
End Class

Module Example
   Public Sub Main()
      Dim people As New List(Of Person)()
      
      people.Add(New Person("John", "Doe"))
      people.Add(New Person("Jane", "Doe"))
      people.Sort()
      For Each person In people
         Console.WriteLine("{0} {1}", person.FirstName, person.LastName)
      Next
   End Sub
End Module
' The example displays the following output:
'    Unhandled Exception: System.InvalidOperationException: Failed to compare two elements in the array. ---> 
'       System.ArgumentException: At least one object must implement IComparable.
'       at System.Collections.Comparer.Compare(Object a, Object b)
'       at System.Collections.Generic.ArraySortHelper`1.SwapIfGreater(T[] keys, IComparer`1 comparer, Int32 a, Int32 b)
'       at System.Collections.Generic.ArraySortHelper`1.DepthLimitedQuickSort(T[] keys, Int32 left, Int32 right, IComparer`1 comparer, Int32 depthLimit)
'       at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
'       --- End of inner exception stack trace ---
'       at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
'       at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
'       at System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer)
'       at Example.Main()

Vous pouvez éliminer l’exception de l’une des trois façons suivantes :You can eliminate the exception in any of three ways:

  • Si vous pouvez posséder le type que vous essayez de trier (c’est-à-dire, si vous contrôlez son code source), vous pouvez le modifier pour implémenter le IComparable<T> ou l’interface IComparable.If you can own the type that you are trying to sort (that is, if you control its source code), you can modify it to implement the IComparable<T> or the IComparable interface. Pour cela, vous devez implémenter l' IComparable<T>.CompareTo ou la méthode CompareTo.This requires that you implement either the IComparable<T>.CompareTo or the CompareTo method. L’ajout d’une implémentation d’interface à un type existant n’est pas une modification avec rupture.Adding an interface implementation to an existing type is not a breaking change.

    L’exemple suivant utilise cette approche pour fournir une implémentation IComparable<T> pour la classe Person.The following example uses this approach to provide an IComparable<T> implementation for the Person class. Vous pouvez toujours appeler la méthode de tri générale de la collection ou du tableau et, comme le montre la sortie de l’exemple, la collection est correctement triée.You can still call the collection or array's general sorting method and, as the output from the example shows, the collection sorts successfully.

    using System;
    using System.Collections.Generic;
    
    public class Person : IComparable<Person>
    {
       public Person(String fName, String lName)
       {
          FirstName = fName;
          LastName = lName;
       }
       
       public String FirstName { get; set; }
       public String LastName { get; set; }
    
       public int CompareTo(Person other)
       {
          return String.Format("{0} {1}", LastName, FirstName).
                 CompareTo(String.Format("{0} {1}", LastName, FirstName));    
       }       
    }
    
    public class Example
    {
       public static void Main()
       {
          var people = new List<Person>();
          
          people.Add(new Person("John", "Doe"));
          people.Add(new Person("Jane", "Doe"));
          people.Sort();
          foreach (var person in people)
             Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
       }
    }
    // The example displays the following output:
    //       Jane Doe
    //       John Doe
    
    Imports System.Collections.Generic
    
    Public Class Person : Implements IComparable(Of Person)
       Public Sub New(fName As String, lName As String)
          FirstName = fName
          LastName = lName
       End Sub
       
       Public Property FirstName As String
       Public Property LastName As String
       
       Public Function CompareTo(other As Person) As Integer _
              Implements IComparable(Of Person).CompareTo
          Return String.Format("{0} {1}", LastName, FirstName).
                 CompareTo(String.Format("{0} {1}", LastName, FirstName))    
       End Function       
    End Class
    
    Module Example
       Public Sub Main()
          Dim people As New List(Of Person)()
          
          people.Add(New Person("John", "Doe"))
          people.Add(New Person("Jane", "Doe"))
          people.Sort()
          For Each person In people
             Console.WriteLine("{0} {1}", person.FirstName, person.LastName)
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '       Jane Doe
    '       John Doe
    
  • Si vous ne pouvez pas modifier le code source pour le type que vous essayez de trier, vous pouvez définir une classe de tri à usage spécifique qui implémente l’interface IComparer<T>.If you cannot modify the source code for the type you are trying to sort, you can define a special-purpose sorting class that implements the IComparer<T> interface. Vous pouvez appeler une surcharge de la méthode Sort qui comprend un paramètre IComparer<T>.You can call an overload of the Sort method that includes an IComparer<T> parameter. Cette approche est particulièrement utile si vous souhaitez développer une classe de tri spécialisée qui peut trier des objets en fonction de plusieurs critères.This approach is especially useful if you want to develop a specialized sorting class that can sort objects based on multiple criteria.

    L’exemple suivant utilise l’approche en développant une classe PersonComparer personnalisée utilisée pour trier les collections Person.The following example uses the approach by developing a custom PersonComparer class that is used to sort Person collections. Il passe ensuite une instance de cette classe à la méthode List<T>.Sort(IComparer<T>).It then passes an instance of this class to the List<T>.Sort(IComparer<T>) method.

    using System;
    using System.Collections.Generic;
    
    public class Person
    {
       public Person(String fName, String lName)
       {
          FirstName = fName;
          LastName = lName;
       }
       
       public String FirstName { get; set; }
       public String LastName { get; set; }
    }
    
    public class PersonComparer : IComparer<Person>
    {
       public int Compare(Person x, Person y) 
       {
          return String.Format("{0} {1}", x.LastName, x.FirstName).
                 CompareTo(String.Format("{0} {1}", y.LastName, y.FirstName));    
       }       
    }
    
    public class Example
    {
       public static void Main()
       {
          var people = new List<Person>();
          
          people.Add(new Person("John", "Doe"));
          people.Add(new Person("Jane", "Doe"));
          people.Sort(new PersonComparer());
          foreach (var person in people)
             Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
       }
    }
    // The example displays the following output:
    //       Jane Doe
    //       John Doe
    
    Imports System.Collections.Generic
    
    Public Class Person
       Public Sub New(fName As String, lName As String)
          FirstName = fName
          LastName = lName
       End Sub
       
       Public Property FirstName As String
       Public Property LastName As String
    End Class
    
    Public Class PersonComparer : Implements IComparer(Of Person)
       Public Function Compare(x As Person, y As Person) As Integer _
              Implements IComparer(Of Person).Compare
          Return String.Format("{0} {1}", x.LastName, x.FirstName).
                 CompareTo(String.Format("{0} {1}", y.LastName, y.FirstName))    
       End Function       
    End Class
    
    Module Example
       Public Sub Main()
          Dim people As New List(Of Person)()
          
          people.Add(New Person("John", "Doe"))
          people.Add(New Person("Jane", "Doe"))
          people.Sort(New PersonComparer())
          For Each person In people
             Console.WriteLine("{0} {1}", person.FirstName, person.LastName)
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '       Jane Doe
    '       John Doe
    
  • Si vous ne pouvez pas modifier le code source pour le type que vous essayez de trier, vous pouvez créer un Comparison<T> délégué pour effectuer le tri.If you cannot modify the source code for the type you are trying to sort, you can create a Comparison<T> delegate to perform the sorting. La signature du délégué estThe delegate signature is

    Function Comparison(Of T)(x As T, y As T) As Integer  
    
    int Comparison<T>(T x, T y)  
    

    L’exemple suivant utilise l’approche en définissant une méthode PersonComparison qui correspond à la signature du délégué Comparison<T>.The following example uses the approach by defining a PersonComparison method that matches the Comparison<T> delegate signature. Il passe ensuite ce délégué à la méthode List<T>.Sort(Comparison<T>).It then passes this delegate to the List<T>.Sort(Comparison<T>) method.

    using System;
    using System.Collections.Generic;
    
    public class Person
    {
       public Person(String fName, String lName)
       {
          FirstName = fName;
          LastName = lName;
       }
       
       public String FirstName { get; set; }
       public String LastName { get; set; }
    }
    
    public class Example
    {
       public static void Main()
       {
          var people = new List<Person>();
          
          people.Add(new Person("John", "Doe"));
          people.Add(new Person("Jane", "Doe"));
          people.Sort(PersonComparison);
          foreach (var person in people)
             Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
       }
    
       public static int PersonComparison(Person x, Person y)
       {
          return String.Format("{0} {1}", x.LastName, x.FirstName).
                 CompareTo(String.Format("{0} {1}", y.LastName, y.FirstName));    
       }
    }
    // The example displays the following output:
    //       Jane Doe
    //       John Doe
    
    Imports System.Collections.Generic
    
    Public Class Person
       Public Sub New(fName As String, lName As String)
          FirstName = fName
          LastName = lName
       End Sub
       
       Public Property FirstName As String
       Public Property LastName As String
    End Class
    
    Module Example
       Public Sub Main()
          Dim people As New List(Of Person)()
          
          people.Add(New Person("John", "Doe"))
          people.Add(New Person("Jane", "Doe"))
          people.Sort(AddressOf PersonComparison)
          For Each person In people
             Console.WriteLine("{0} {1}", person.FirstName, person.LastName)
          Next
       End Sub
       
       Public Function PersonComparison(x As Person, y As Person) As Integer
          Return String.Format("{0} {1}", x.LastName, x.FirstName).
                 CompareTo(String.Format("{0} {1}", y.LastName, y.FirstName))    
       End Function
    End Module
    ' The example displays the following output:
    '       Jane Doe
    '       John Doe
    

Cast d’un<T Nullable > null en son type sous-jacentCasting a Nullable<T> that is null to its underlying type

Toute tentative d’effectuer un cast d’une valeur Nullable<T> qui est null à son type sous-jacent lève une exception InvalidOperationException et affiche le message d’erreur «un objet Nullable doit avoir une valeur.Attempting to cast a Nullable<T> value that is null to its underlying type throws an InvalidOperationException exception and displays the error message, "Nullable object must have a value.

L’exemple suivant lève une exception InvalidOperationException lorsqu’il tente d’itérer un tableau qui comprend une valeur de Nullable(Of Integer).The following example throws an InvalidOperationException exception when it attempts to iterate an array that includes a Nullable(Of Integer) value.

using System;
using System.Linq;

public class Example
{
   public static void Main()
   {
      var queryResult = new int?[] { 1, 2, null, 4 };
      var map = queryResult.Select(nullableInt => (int)nullableInt);
      
      // Display list.
      foreach (var num in map)
         Console.Write("{0} ", num);
      Console.WriteLine();   
   }
}
// The example displays the following output:
//    1 2
//    Unhandled Exception: System.InvalidOperationException: Nullable object must have a value.
//       at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
//       at Example.<Main>b__0(Nullable`1 nullableInt)
//       at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
//       at Example.Main()
Imports System.Linq

Module Example
   Public Sub Main()
      Dim queryResult = New Integer?() { 1, 2, Nothing, 4 }
      Dim map = queryResult.Select(Function(nullableInt) CInt(nullableInt))
      
      ' Display list.
      For Each num In map
         Console.Write("{0} ", num)
      Next
      Console.WriteLine()   
   End Sub
End Module
' The example displays thIe following output:
'    1 2
'    Unhandled Exception: System.InvalidOperationException: Nullable object must have a value.
'       at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
'       at Example.<Main>b__0(Nullable`1 nullableInt)
'       at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
'       at Example.Main()

Pour éviter l’exception :To prevent the exception:

L’exemple suivant effectue les deux pour éviter l’exception InvalidOperationException.The following example does both to avoid the InvalidOperationException exception.

using System;
using System.Linq;

public class Example
{
   public static void Main()
   {
      var queryResult = new int?[] { 1, 2, null, 4 };
      var numbers = queryResult.Select(nullableInt => (int)nullableInt.GetValueOrDefault());
      
      // Display list using Nullable<int>.HasValue.
      foreach (var number in numbers)
         Console.Write("{0} ", number);
      Console.WriteLine();   
      
      numbers = queryResult.Select(nullableInt => (int) (nullableInt.HasValue ? nullableInt : -1));
      // Display list using Nullable<int>.GetValueOrDefault.
      foreach (var number in numbers)
         Console.Write("{0} ", number);
      Console.WriteLine();   
   }
}
// The example displays the following output:
//       1 2 0 4
//       1 2 -1 4
Imports System.Linq

Module Example
   Public Sub Main()
      Dim queryResult = New Integer?() { 1, 2, Nothing, 4 }
      Dim numbers = queryResult.Select(Function(nullableInt) _ 
                                          CInt(nullableInt.GetValueOrDefault()))
      ' Display list.
      For Each number In numbers
         Console.Write("{0} ", number)
      Next
      Console.WriteLine()
      
      ' Use -1 to indicate a missing values.
      numbers = queryResult.Select(Function(nullableInt) _   
                                      CInt(If(nullableInt.HasValue, nullableInt, -1)))
      ' Display list.
      For Each number In numbers
         Console.Write("{0} ", number)
      Next
      Console.WriteLine()
                                      
   End Sub
End Module
' The example displays the following output:
'       1 2 0 4
'       1 2 -1 4

Appel d’une méthode System. Linq. Enumerable sur une collection videCalling a System.Linq.Enumerable method on an empty collection

Les méthodes Enumerable.Aggregate, Enumerable.Average, Enumerable.First, Enumerable.Last, Enumerable.Max, Enumerable.Min, Enumerable.Singleet Enumerable.SingleOrDefault effectuent des opérations sur une séquence et retournent un résultat unique.The Enumerable.Aggregate, Enumerable.Average, Enumerable.First, Enumerable.Last, Enumerable.Max, Enumerable.Min, Enumerable.Single, and Enumerable.SingleOrDefault methods perform operations on a sequence and return a single result. Certaines surcharges de ces méthodes lèvent une exception InvalidOperationException lorsque la séquence est vide, tandis que d’autres surcharges retournent null.Some overloads of these methods throw an InvalidOperationException exception when the sequence is empty, while other overloads return null. La méthode Enumerable.SingleOrDefault lève également une exception InvalidOperationException quand la séquence contient plusieurs éléments.The Enumerable.SingleOrDefault method also throws an InvalidOperationException exception when the sequence contains more than one element.

Notes

La plupart des méthodes qui lèvent une exception InvalidOperationException sont des surcharges.Most of the methods that throw an InvalidOperationException exception are overloads. Veillez à bien comprendre le comportement de la surcharge que vous choisissez.Be sure that you understand the behavior of the overload that you choose.

Le tableau suivant répertorie les messages d’exception des InvalidOperationException objets exception levés par les appels à certaines méthodes System.Linq.Enumerable.The following table lists the exception messages from the InvalidOperationException exception objects thrown by calls to some System.Linq.Enumerable methods.

MéthodeMethod MessageMessage
Aggregate
Average
Last
Max
Min
La séquence ne contient aucun élémentSequence contains no elements
First La séquence ne contient aucun élément correspondantSequence contains no matching element
Single
SingleOrDefault
La séquence contient plusieurs éléments correspondantsSequence contains more than one matching element

La façon dont vous éliminez ou gérez l’exception dépend des hypothèses de votre application et de la méthode particulière que vous appelez.How you eliminate or handle the exception depends on your application's assumptions and on the particular method you call.

  • Lorsque vous appelez délibérément l’une de ces méthodes sans vérifier la présence d’une séquence vide, vous supposez que la séquence n’est pas vide et qu’une séquence vide est un événement inattendu.When you deliberately call one of these methods without checking for an empty sequence, you are assuming that the sequence is not empty, and that an empty sequence is an unexpected occurrence. Dans ce cas, le fait d’intercepter ou de lever à nouveau l’exception est approprié.In this case, catching or rethrowing the exception is appropriate .

  • Si vous ne parvenez pas à rechercher une séquence vide, vous pouvez appeler l’une des surcharges de la surcharge Enumerable.Any pour déterminer si une séquence contient des éléments.If your failure to check for an empty sequence was inadvertent, you can call one of the overloads of the Enumerable.Any overload to determine whether a sequence contains any elements.

    Conseil

    L’appel de la méthode Enumerable.Any<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) avant la génération d’une séquence peut améliorer les performances si les données à traiter peuvent contenir un grand nombre d’éléments ou si l’opération qui génère la séquence est coûteuse.Calling the Enumerable.Any<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) method before generating a sequence can improve performance if the data to be processed might contain a large number of elements or if operation that generates the sequence is expensive.

  • Si vous avez appelé une méthode telle que Enumerable.First, Enumerable.Lastou Enumerable.Single, vous pouvez substituer une autre méthode, telle que Enumerable.FirstOrDefault, Enumerable.LastOrDefaultou Enumerable.SingleOrDefault, qui retourne une valeur par défaut au lieu d’un membre de la séquence.If you've called a method such as Enumerable.First, Enumerable.Last, or Enumerable.Single, you can substitute an alternate method, such as Enumerable.FirstOrDefault, Enumerable.LastOrDefault, or Enumerable.SingleOrDefault, that returns a default value instead of a member of the sequence.

Les exemples fournissent des détails supplémentaires.The examples provide additional detail.

L’exemple suivant utilise la méthode Enumerable.Average pour calculer la moyenne d’une séquence dont les valeurs sont supérieures à 4.The following example uses the Enumerable.Average method to compute the average of a sequence whose values are greater than 4. Dans la mesure où aucune valeur du tableau d’origine ne dépasse 4, aucune valeur n’est incluse dans la séquence, et la méthode lève une exception InvalidOperationException.Since no values from the original array exceed 4, no values are included in the sequence, and the method throws an InvalidOperationException exception.

using System;
using System.Linq;

public class Example
{
   public static void Main()
   {
      int[] data = { 1, 2, 3, 4 };
      var average = data.Where(num => num > 4).Average();
      Console.Write("The average of numbers greater than 4 is {0}",
                    average);
   }
}
// The example displays the following output:
//    Unhandled Exception: System.InvalidOperationException: Sequence contains no elements
//       at System.Linq.Enumerable.Average(IEnumerable`1 source)
//       at Example.Main()
Imports System.Linq

Module Example
   Public Sub Main()
      Dim data() As Integer = { 1, 2, 3, 4 }
      Dim average = data.Where(Function(num) num > 4).Average()
      Console.Write("The average of numbers greater than 4 is {0}",
                    average)
   End Sub
End Module
' The example displays the following output:
'    Unhandled Exception: System.InvalidOperationException: Sequence contains no elements
'       at System.Linq.Enumerable.Average(IEnumerable`1 source)
'       at Example.Main()

L’exception peut être éliminée en appelant la méthode Any pour déterminer si la séquence contient des éléments avant d’appeler la méthode qui traite la séquence, comme le montre l’exemple suivant.The exception can be eliminated by calling the Any method to determine whether the sequence contains any elements before calling the method that processes the sequence, as the following example shows.

using System;
using System.Linq;

public class Example
{
   public static void Main()
   {
       int[] dbQueryResults = { 1, 2, 3, 4 };
       var moreThan4 = dbQueryResults.Where(num => num > 4);
   
       if(moreThan4.Any())
           Console.WriteLine("Average value of numbers greater than 4: {0}:", 
                             moreThan4.Average());
       else
           // handle empty collection 
           Console.WriteLine("The dataset has no values greater than 4.");
   }
}
// The example displays the following output:
//       The dataset has no values greater than 4.
Imports System.Linq

Module Example
   Public Sub Main()
       Dim dbQueryResults() As Integer = { 1, 2, 3, 4 }
       Dim moreThan4 = dbQueryResults.Where(Function(num) num > 4)
   
       If moreThan4.Any() Then
           Console.WriteLine("Average value of numbers greater than 4: {0}:", 
                             moreThan4.Average())
       Else
           ' Handle empty collection. 
           Console.WriteLine("The dataset has no values greater than 4.")
       End If    
   End Sub
End Module
' The example displays the following output:
'       The dataset has no values greater than 4.

La méthode Enumerable.First retourne le premier élément d’une séquence ou le premier élément d’une séquence qui satisfait à une condition spécifiée.The Enumerable.First method returns the first item in a sequence or the first element in a sequence that satisfies a specified condition. Si la séquence est vide et n’a donc pas de premier élément, elle lève une exception InvalidOperationException.If the sequence is empty and therefore does not have a first element, it throws an InvalidOperationException exception.

Dans l’exemple suivant, la méthode Enumerable.First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) lève une exception InvalidOperationException, car le tableau dbQueryResults ne contient pas d’élément supérieur à 4.In the following example, the Enumerable.First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) method throws an InvalidOperationException exception because the dbQueryResults array doesn't contain an element greater than 4.

using System;
using System.Linq;

public class Example
{
   public static void Main()
   {
      int[] dbQueryResults = { 1, 2, 3, 4 };

      var firstNum = dbQueryResults.First(n => n > 4);

      Console.WriteLine("The first value greater than 4 is {0}", 
                        firstNum);
   }
}
// The example displays the following output:
//    Unhandled Exception: System.InvalidOperationException: 
//       Sequence contains no matching element
//       at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
//       at Example.Main()
Imports System.Linq

Module Example
   Public Sub Main()
      Dim dbQueryResults() As Integer = { 1, 2, 3, 4 }

      Dim firstNum = dbQueryResults.First(Function(n) n > 4)

      Console.WriteLine("The first value greater than 4 is {0}", 
                        firstNum)
   End Sub
End Module
' The example displays the following output:
'    Unhandled Exception: System.InvalidOperationException: 
'       Sequence contains no matching element
'       at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
'       at Example.Main()

Vous pouvez appeler la méthode Enumerable.FirstOrDefault au lieu de Enumerable.First pour retourner une valeur spécifiée ou par défaut.You can call the Enumerable.FirstOrDefault method instead of Enumerable.First to return a specified or default value. Si la méthode ne trouve pas de premier élément dans la séquence, elle retourne la valeur par défaut de ce type de données.If the method does not find a first element in the sequence, it returns the default value for that data type. La valeur par défaut est null pour un type de référence, zéro pour un type de données numérique et DateTime.MinValue pour le type de DateTime.The default value is null for a reference type, zero for a numeric data type, and DateTime.MinValue for the DateTime type.

Notes

L’interprétation de la valeur retournée par la méthode Enumerable.FirstOrDefault est souvent compliquée par le fait que la valeur par défaut du type peut être une valeur valide dans la séquence.Interpreting the value returned by the Enumerable.FirstOrDefault method is often complicated by the fact that the default value of the type can be a valid value in the sequence. Dans ce cas, vous appelez la méthode Enumerable.Any pour déterminer si la séquence a des membres valides avant d’appeler la méthode Enumerable.First.In this case, you an call the Enumerable.Any method to determine whether the sequence has valid members before calling the Enumerable.First method.

L’exemple suivant appelle la méthode Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) pour empêcher l’exception InvalidOperationException levée dans l’exemple précédent.The following example calls the Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) method to prevent the InvalidOperationException exception thrown in the previous example.

using System;
using System.Linq;

public class Example
{
   public static void Main()
   {
      int[] dbQueryResults = { 1, 2, 3, 4 };

      var firstNum = dbQueryResults.FirstOrDefault(n => n > 4);

      if (firstNum == 0)
         Console.WriteLine("No value is greater than 4.");
      else   
         Console.WriteLine("The first value greater than 4 is {0}", 
                           firstNum);
   }
}
// The example displays the following output:
//       No value is greater than 4.
Imports System.Linq

Module Example
   Public Sub Main()
      Dim dbQueryResults() As Integer = { 1, 2, 3, 4 }

      Dim firstNum = dbQueryResults.FirstOrDefault(Function(n) n > 4)

      If firstNum = 0 Then
         Console.WriteLIne("No value is greater than 4.")
      Else   
         Console.WriteLine("The first value greater than 4 is {0}", 
                           firstNum)
      End If                     
   End Sub
End Module
' The example displays the following output:
'       No value is greater than 4.

Appel de Enumerable. Single ou Enumerable. SingleOrDefault sur une séquence sans élémentCalling Enumerable.Single or Enumerable.SingleOrDefault on a sequence without one element

La méthode Enumerable.Single retourne le seul élément d’une séquence ou le seul élément d’une séquence qui répond à une condition spécifiée.The Enumerable.Single method returns the only element of a sequence, or the only element of a sequence that meets a specified condition. S’il n’y a aucun élément dans la séquence, ou s’il y a plusieurs éléments, la méthode lève une exception InvalidOperationException.If there are no elements in the sequence, or if there is more than one element , the method throws an InvalidOperationException exception.

Vous pouvez utiliser la méthode Enumerable.SingleOrDefault pour retourner une valeur par défaut au lieu de lever une exception lorsque la séquence ne contient aucun élément.You can use the Enumerable.SingleOrDefault method to return a default value instead of throwing an exception when the sequence contains no elements. Toutefois, la méthode Enumerable.SingleOrDefault lève toujours une exception InvalidOperationException quand la séquence contient plusieurs éléments.However, the Enumerable.SingleOrDefault method still throws an InvalidOperationException exception when the sequence contains more than one element.

Le tableau suivant répertorie les messages d’exception des InvalidOperationException objets exception levés par les appels aux méthodes Enumerable.Single et Enumerable.SingleOrDefault.The following table lists the exception messages from the InvalidOperationException exception objects thrown by calls to the Enumerable.Single and Enumerable.SingleOrDefault methods.

MéthodeMethod MessageMessage
Single La séquence ne contient aucun élément correspondantSequence contains no matching element
Single
SingleOrDefault
La séquence contient plusieurs éléments correspondantsSequence contains more than one matching element

Dans l’exemple suivant, l’appel à la méthode Enumerable.Single lève une exception InvalidOperationException, car la séquence n’a pas d’élément supérieur à 4.In the following example, the call to the Enumerable.Single method throws an InvalidOperationException exception because the sequence doesn't have an element greater than 4.

using System;
using System.Linq;

public class Example
{
   public static void Main()
   {
       int[] dbQueryResults = { 1, 2, 3, 4 };
   
       var singleObject = dbQueryResults.Single(value => value > 4);
   
       // Display results.
       Console.WriteLine("{0} is the only value greater than 4", singleObject);
   }
}
// The example displays the following output:
//    Unhandled Exception: System.InvalidOperationException: 
//       Sequence contains no matching element
//       at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
//       at Example.Main()
Imports System.Linq

Module Example
   Public Sub Main()
       Dim dbQueryResults() As Integer = { 1, 2, 3, 4 }
   
       Dim singleObject = dbQueryResults.Single(Function(value) value > 4)
   
       ' Display results.
       Console.WriteLine("{0} is the only value greater than 4", 
                         singleObject)
   End Sub
End Module
' The example displays the following output:
'    Unhandled Exception: System.InvalidOperationException: 
'       Sequence contains no matching element
'       at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
'       at Example.Main()

L’exemple suivant tente d’empêcher l’exception InvalidOperationException levée lorsqu’une séquence est vide en appelant à la place la méthode Enumerable.SingleOrDefault.The following example attempts to prevent the InvalidOperationException exception thrown when a sequence is empty by instead calling the Enumerable.SingleOrDefault method. Toutefois, étant donné que cette séquence retourne plusieurs éléments dont la valeur est supérieure à 2, elle lève également une exception InvalidOperationException.However, because this sequence returns multiple elements whose value is greater than 2, it also throws an InvalidOperationException exception.

using System;
using System.Linq;

public class Example
{
   public static void Main()
   {
       int[] dbQueryResults = { 1, 2, 3, 4 };
   
       var singleObject = dbQueryResults.SingleOrDefault(value => value > 2);
   
       if (singleObject != 0)
           Console.WriteLine("{0} is the only value greater than 2", 
                             singleObject);
       else
           // Handle an empty collection.
           Console.WriteLine("No value is greater than 2");
   }
}
// The example displays the following output:
//    Unhandled Exception: System.InvalidOperationException: 
//       Sequence contains more than one matching element
//       at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
//       at Example.Main()
Imports System.Linq

Module Example
   Public Sub Main()
       Dim dbQueryResults() As Integer = { 1, 2, 3, 4 }
   
       Dim singleObject = dbQueryResults.SingleOrDefault(Function(value) value > 2)
   
       If singleObject <> 0 Then
           Console.WriteLine("{0} is the only value greater than 2", 
                             singleObject)
       Else
           ' Handle an empty collection.
           Console.WriteLine("No value is greater than 2")
       End If    
   End Sub
End Module
' The example displays the following output:
'    Unhandled Exception: System.InvalidOperationException: 
'       Sequence contains more than one matching element
'       at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
'       at Example.Main()

L’appel de la méthode Enumerable.Single suppose qu’une séquence ou la séquence qui répond aux critères spécifiés contient un seul élément.Calling the Enumerable.Single method assumes that either a sequence or the sequence that meets specified criteria contains only one element. Enumerable.SingleOrDefault suppose une séquence avec zéro ou un résultat, mais pas plus.Enumerable.SingleOrDefault assumes a sequence with zero or one result, but no more. S’il s’agit d’une hypothèse délibérée de votre part et que ces conditions ne sont pas remplies, il convient de lever à nouveau ou d’intercepter le InvalidOperationException qui en résulte.If this assumption is a deliberate one on your part and these conditions are not met, rethrowing or catching the resulting InvalidOperationException is appropriate. Dans le cas contraire, ou si vous pensez que des conditions non valides se produiront avec une certaine fréquence, vous devez envisager d’utiliser une autre méthode Enumerable, telle que FirstOrDefault ou Where.Otherwise, or if you expect that invalid conditions will occur with some frequency, you should consider using some other Enumerable method, such as FirstOrDefault or Where.

Accès au champ de domaine d’application croisé dynamiqueDynamic cross-application domain field access

L’instruction MSIL (Microsoft Intermediate Language) OpCodes.Ldflda lève une exception InvalidOperationException si l’objet contenant le champ dont vous essayez d’extraire l’adresse n’est pas dans le domaine d’application dans lequel votre code s’exécute.The OpCodes.Ldflda Microsoft intermediate language (MSIL) instruction throws an InvalidOperationException exception if the object containing the field whose address you are trying to retrieve is not within the application domain in which your code is executing. L’adresse d’un champ est accessible uniquement à partir du domaine d’application dans lequel il réside.The address of a field can only be accessed from the application domain in which it resides.

Levée d’une exception InvalidOperationExceptionThrowing an InvalidOperationException exception

Vous devez lever une exception InvalidOperationException uniquement lorsque l’état de votre objet pour une raison quelconque ne prend pas en charge un appel de méthode particulier.You should throw an InvalidOperationException exception only when the state of your object for some reason does not support a particular method call. Autrement dit, l’appel de méthode est valide dans certaines circonstances ou certains contextes, mais n’est pas valide dans d’autres.That is, the method call is valid in some circumstances or contexts, but is invalid in others.

Si l’échec de l’appel de la méthode est dû à des arguments non valides, ArgumentException ou l’une de ses classes dérivées, ArgumentNullException ou ArgumentOutOfRangeException, doit être levée à la place.If the method invocation failure is due to invalid arguments, then ArgumentException or one of its derived classes, ArgumentNullException or ArgumentOutOfRangeException, should be thrown instead.

Informations diversesMiscellaneous information

InvalidOperationException utilise le COR_E_INVALIDOPERATION HRESULT, qui a la valeur 0x80131509.InvalidOperationException uses the HRESULT COR_E_INVALIDOPERATION, which has the value 0x80131509.

Pour obtenir la liste des valeurs initiales des propriétés d’une instance de InvalidOperationException, consultez le InvalidOperationException constructeurs.For a list of initial property values for an instance of InvalidOperationException, see the InvalidOperationException constructors.

Constructeurs

InvalidOperationException()

Initialise une nouvelle instance de la classe InvalidOperationException.Initializes a new instance of the InvalidOperationException class.

InvalidOperationException(SerializationInfo, StreamingContext)

Initialise une nouvelle instance de la classe InvalidOperationException avec des données sérialisées.Initializes a new instance of the InvalidOperationException class with serialized data.

InvalidOperationException(String)

Initialise une nouvelle instance de la classe InvalidOperationException avec un message d'erreur spécifié.Initializes a new instance of the InvalidOperationException class with a specified error message.

InvalidOperationException(String, Exception)

Initialise une nouvelle instance de la classe InvalidOperationException avec un message d'erreur spécifié et une référence à l'exception interne ayant provoqué cette exception.Initializes a new instance of the InvalidOperationException class with a specified error message and a reference to the inner exception that is the cause of this exception.

Propriétés

Data

Obtient une collection de paires clé/valeur qui fournissent des informations supplémentaires définies par l’utilisateur sur l’exception.Gets a collection of key/value pairs that provide additional user-defined information about the exception.

(Hérité de Exception)
HelpLink

Obtient ou définit un lien vers le fichier d'aide associé à cette exception.Gets or sets a link to the help file associated with this exception.

(Hérité de Exception)
HResult

Obtient ou définit HRESULT, valeur numérique codée qui est assignée à une exception spécifique.Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.

(Hérité de Exception)
InnerException

Obtient l'instance Exception qui a provoqué l'exception actuelle.Gets the Exception instance that caused the current exception.

(Hérité de Exception)
Message

Obtient un message qui décrit l'exception actuelle.Gets a message that describes the current exception.

(Hérité de Exception)
Source

Obtient ou définit le nom de l'application ou de l'objet qui est à l'origine de l'erreur.Gets or sets the name of the application or the object that causes the error.

(Hérité de Exception)
StackTrace

Obtient une représentation sous forme de chaîne des frames immédiats sur la pile des appels.Gets a string representation of the immediate frames on the call stack.

(Hérité de Exception)
TargetSite

Obtient la méthode qui lève l'exception actuelle.Gets the method that throws the current exception.

(Hérité de Exception)

Méthodes

Equals(Object)

Détermine si l'objet spécifié est égal à l'objet actuel.Determines whether the specified object is equal to the current object.

(Hérité de Object)
GetBaseException()

En cas de substitution dans une classe dérivée, retourne la Exception qui est à l'origine d'une ou de plusieurs exceptions ultérieures.When overridden in a derived class, returns the Exception that is the root cause of one or more subsequent exceptions.

(Hérité de Exception)
GetHashCode()

Sert de fonction de hachage par défaut.Serves as the default hash function.

(Hérité de Object)
GetObjectData(SerializationInfo, StreamingContext)

En cas de substitution dans une classe dérivée, définit SerializationInfo avec des informations sur l'exception.When overridden in a derived class, sets the SerializationInfo with information about the exception.

(Hérité de Exception)
GetType()

Obtient le type au moment de l'exécution de l'instance actuelle.Gets the runtime type of the current instance.

(Hérité de Exception)
MemberwiseClone()

Crée une copie superficielle du Object actuel.Creates a shallow copy of the current Object.

(Hérité de Object)
ToString()

Crée et retourne une chaîne représentant l'exception actuelle.Creates and returns a string representation of the current exception.

(Hérité de Exception)

Événements

SerializeObjectState

Se produit quand une exception est sérialisée pour créer un objet d'état d'exception qui contient des données sérialisées concernant l'exception.Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.

(Hérité de Exception)

S’applique à

Voir aussi