InvalidOperationException InvalidOperationException InvalidOperationException InvalidOperationException Class

Definizione

Eccezione generata quando una chiamata a un metodo non è valida per lo stato corrente dell'oggetto.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
Ereditarietà
InvalidOperationExceptionInvalidOperationExceptionInvalidOperationExceptionInvalidOperationException
Derivato
Attributi

Commenti

InvalidOperationException viene utilizzato nei casi quando l'impossibilità di richiamare un metodo è causato da motivi diversi da argomenti non validi.InvalidOperationException is used in cases when the failure to invoke a method is caused by reasons other than invalid arguments. In genere, viene generata quando lo stato di un oggetto non supporta la chiamata al metodo.Typically, it is thrown when the state of an object cannot support the method call. Ad esempio, un InvalidOperationException eccezione viene generata dai metodi, ad esempio:For example, an InvalidOperationException exception is thrown by methods such as:

Importante

Poiché il InvalidOperationException possono essere generate eccezioni in un'ampia gamma di circostanze, è importante leggere il messaggio di eccezione restituito dal Message proprietà.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.

Contenuto della sezione:In this section:

Alcune cause comuni di eccezioni InvalidOperationException Some common causes of InvalidOperationException exceptions
L'aggiornamento di un thread dell'interfaccia utente da un thread non UIUpdating a UI thread from a non-UI thread
Modifica di una raccolta durante lo scorrimentoChanging a collection while iterating it
L'ordinamento di una matrice o raccolta di oggetti di cui non è possibile confrontareSorting an array or collection whose objects cannot be compared
Esegue il cast di un tipo Nullable<T> null al relativo tipo sottostante Casting a Nullable<T> that is null to its underlying type
Chiamare un metodo Enumerable su una raccolta vuotaCalling a System.Linq.Enumerable method on an empty collection
Chiamare il metodo Enumerable o SingleOrDefault su una sequenza senza un elementoCalling Enumerable.Single or Enumerable.SingleOrDefault on a sequence without one element
Accesso al campo dinamico tra domini delle applicazioniDynamic cross-application domain field access
Generare un'eccezione InvalidOperationExceptionThrowing an InvalidOperationException exception
Informazioni di vario tipoMiscellaneous information

Alcune cause comuni di eccezioni InvalidOperationExceptionSome common causes of InvalidOperationException exceptions

Le sezioni seguenti mostrano come i casi in cui in alcuni comuni InvalidOperationException eccezione viene generata in un'app.The following sections show how some common cases in which in InvalidOperationException exception is thrown in an app. Modalità di gestione del problema varia a seconda della situazione specifica.How you handle the issue depends on the specific situation. In genere, tuttavia, l'eccezione risultante dall'errore per gli sviluppatori e il InvalidOperationException eccezioni possono essere previste ed evitate.Most commonly, however, the exception results from developer error, and the InvalidOperationException exception can be anticipated and avoided.

L'aggiornamento di un thread dell'interfaccia utente da un thread non UIUpdating a UI thread from a non-UI thread

Thread di lavoro vengono spesso usati per eseguire alcune operazioni in background che include la raccolta di dati da visualizzare nell'interfaccia utente di un'applicazione.Often, worker threads are used to perform some background work that involves gathering data to be displayed in an application's user interface. Tuttavia.However. la maggior parte dei framework di applicazione GUI (interfaccia utente grafica) per .NET Framework, ad esempio Windows Form e Windows Presentation Foundation (WPF), consentono di accedere agli oggetti della GUI solo dal thread che crea e gestisce l'interfaccia utente (il thread principale o dell'interfaccia utente).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). Un InvalidOperationException viene generata quando si tenta di accedere a un elemento dell'interfaccia utente da un thread diverso da quello dell'interfaccia utente.An InvalidOperationException is thrown when you try to access a UI element from a thread other than the UI thread. Nella tabella seguente viene mostrato il testo del messaggio dell'eccezione.The text of the exception message is shown in the following table.

Tipo di applicazioneApplication Type MessaggioMessage
App WPFWPF app Il thread chiamante non può accedere a questo oggetto perché un altro thread ne è proprietario.The calling thread cannot access this object because a different thread owns it.
App UWPUWP app L'applicazione ha chiamato un'interfaccia che è stato effettuato il marshalling per un altro thread.The application called an interface that was marshaled for a different thread.
App di Windows. FormsWindows Forms app Operazione di cross-thread non è valido: Controllo 'TextBox1' accessibile da un thread diverso da quello è stato creato.Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on.

Framework dell'interfaccia utente per .NET Framework implementano un dispatcher modello che include un metodo per verificare se una chiamata a un membro di un elemento dell'interfaccia utente viene eseguita sul thread UI e altri metodi per pianificare la chiamata sul thread dell'interfaccia utente: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:

  • Nelle App WPF, chiamare il Dispatcher.CheckAccess metodo per determinare se un metodo è in esecuzione su un thread non dell'interfaccia utente.In WPF apps, call the Dispatcher.CheckAccess method to determine if a method is running on a non-UI thread. Viene restituito true se il metodo è in esecuzione sul thread UI e false in caso contrario.It returns true if the method is running on the UI thread and false otherwise. Chiamare uno degli overload del Dispatcher.Invoke metodo per pianificare la chiamata sul thread dell'interfaccia utente.Call one of the overloads of the Dispatcher.Invoke method to schedule the call on the UI thread.

  • Nelle App UWP, chiamare il CoreDispatcher.HasThreadAccess metodo per determinare se un metodo è in esecuzione su un thread non dell'interfaccia utente.In UWP apps, call the CoreDispatcher.HasThreadAccess method to determine if a method is running on a non-UI thread. Chiamare il CoreDispatcher.RunAsync metodo da eseguire un delegato che aggiorna il thread dell'interfaccia utente.Call the CoreDispatcher.RunAsync method to execute a delegate that updates the UI thread. Usa il comandoUse the

  • Nelle app di Windows Form, usare il Control.InvokeRequired proprietà per determinare se un metodo è in esecuzione su un thread non dell'interfaccia utente.In Windows Forms apps, use the Control.InvokeRequired property to determine if a method is running on a non-UI thread. Chiamare uno degli overload del Control.Invoke metodo da eseguire un delegato che aggiorna il thread dell'interfaccia utente.Call one of the overloads of the Control.Invoke method to execute a delegate that updates the UI thread.

Gli esempi seguenti illustrano il InvalidOperationException eccezione generata quando si prova ad aggiornare un elemento dell'interfaccia utente da un thread diverso da quello che l'ha creata.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. Ogni esempio è necessario creare due controlli:Each example requires that you create two controls:

  • Controllo casella di testo denominato textBox1.A text box control named textBox1. In un'app di Windows Form, è consigliabile impostare relativi Multiline proprietà true.In a Windows Forms app, you should set its Multiline property to true.

  • Un controllo button denominato threadExampleBtn.A button control named threadExampleBtn. Nell'esempio viene fornito un gestore ThreadsExampleBtn_Click, per il pulsante Click evento.The example provides a handler, ThreadsExampleBtn_Click, for the button's Click event.

In ogni caso, il threadExampleBtn_Click chiamate del gestore eventi di DoSomeWork metodo due volte.In each case, the threadExampleBtn_Click event handler calls the DoSomeWork method twice. La prima chiamata viene eseguita in modo sincrono e ha esito positivo.The first call runs synchronously and succeeds. Ma la seconda chiamata, in quanto viene eseguito in modo asincrono in un pool di thread, prova ad aggiornare l'interfaccia utente da un thread non dell'interfaccia utente.But the second call, because it runs asynchronously on a thread pool thread, attempts to update the UI from a non-UI thread. Ciò comporta un InvalidOperationException eccezione.This results in a InvalidOperationException exception.

App WPF e 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 versione seguente del DoSomeWork metodo elimina l'eccezione in un'app 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 versione seguente del DoSomeWork metodo elimina l'eccezione in un'app 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

App di Windows FormWindows 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 versione seguente del DoSomeWork metodo elimina l'eccezione in un'app di Windows Form.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

Modifica di una raccolta durante lo scorrimentoChanging a collection while iterating it

Il foreach istruzione in c# o For Each istruzione in Visual Basic viene utilizzata per scorrere i membri di una raccolta e per leggere o modificare i singoli elementi.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. Tuttavia, non può essere utilizzato per aggiungere o rimuovere elementi dalla raccolta.However, it can't be used to add or remove items from the collection. Tale operazione viene generata una InvalidOperationException eccezione con un messaggio simile a, "insieme è stato modificato; Impossibile eseguire l'operazione di enumerazione. "Doing this throws an InvalidOperationException exception with a message that is similar to, "Collection was modified; enumeration operation may not execute."

Nell'esempio seguente scorre che una raccolta di valori interi tenta di aggiungere il quadrato di ogni valore integer all'insieme.The following example iterates a collection of integers attempts to add the square of each integer to the collection. L'esempio genera una InvalidOperationException con la prima chiamata al List<T>.Add (metodo).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()

È possibile eliminare l'eccezione in uno dei due modi, a seconda della logica dell'applicazione:You can eliminate the exception in one of two ways, depending on your application logic:

  • Se è necessario aggiungere elementi alla raccolta durante lo scorrimento, è possibile alternare indice usando il for istruzione anziché foreach o 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'esempio seguente usa l'istruzione aggiungere il quadrato dei numeri nella raccolta alla raccolta.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
    

    Si noti che è necessario stabilire il numero di iterazioni prima di iterare la raccolta tramite l'utilizzo di un contatore all'interno del ciclo che terminerà il ciclo in modo appropriato, eseguendo l'iterazione all'indietro, da Count - 1 a 0, o, come avviene nell'esempio, assegnando il numero di elementi nella matrice a una variabile e usarlo per stabilire il limite superiore del ciclo.Note 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. In caso contrario, se un elemento viene aggiunto alla raccolta in ogni iterazione, si verificherà un ciclo infinito.Otherwise, if an element is added to the collection on every iteration, an endless loop results.

  • Se non è necessario aggiungere elementi alla raccolta durante lo scorrimento, è possibile archiviare gli elementi da aggiungere in una raccolta temporanea che aggiungere quando ha terminato l'iterazione della raccolta.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'esempio seguente usa questo approccio per aggiungere il quadrato dei numeri in una raccolta a una raccolta temporanea e poi combinare le raccolte in un singolo oggetto di matrice.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
    

L'ordinamento di una matrice o raccolta di oggetti di cui non è possibile confrontareSorting an array or collection whose objects cannot be compared

Per utilizzo generico di ordinamento, ad esempio metodi, il Array.Sort(Array) (metodo) o il List<T>.Sort() metodo, in genere richiedono che almeno uno degli oggetti da ordinare implementare il IComparable<T> o il IComparable interfaccia.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. Caso contrario, la raccolta o una matrice non può essere ordinati, e il metodo genera un InvalidOperationException eccezione.If not, the collection or array cannot be sorted, and the method throws an InvalidOperationException exception. L'esempio seguente definisce una Person classe archivia due Person gli oggetti in un oggetto generico List<T> oggetto e tenta di eseguirne l'ordinamento.The following example defines a Person class, stores two Person objects in a generic List<T> object, and attempts to sort them. Come l'output illustrato nell'esempio, la chiamata ai List<T>.Sort() metodo genera un 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()

È possibile eliminare l'eccezione in uno dei tre modi:You can eliminate the exception in any of three ways:

  • Se si può possedere il tipo che si sta tentando di eseguire l'ordinamento (vale a dire, se si controlla il codice sorgente), è possibile modificarlo per implementare il IComparable<T> o il IComparable interfaccia.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. Ciò richiede che si implementa il IComparable<T>.CompareTo o il CompareTo (metodo).This requires that you implement either the IComparable<T>.CompareTo or the CompareTo method. Aggiunta di un'implementazione dell'interfaccia a un tipo esistente non è una modifica sostanziale.Adding an interface implementation to an existing type is not a breaking change.

    L'esempio seguente usa questo approccio per fornire un' IComparable<T> implementazione per il Person classe.The following example uses this approach to provide an IComparable<T> implementation for the Person class. È comunque possibile chiamare la raccolta o un metodo di ordinamento generale dell'array e, come illustrato nell'output dell'esempio, la raccolta vengono ordinati correttamente.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
    
  • Se non è possibile modificare il codice sorgente per il tipo di cui si sta tentando di ordinamento, è possibile definire una classe di ordinamento con finalità speciali che implementa il IComparer<T> interfaccia.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. È possibile chiamare un overload del Sort metodo che includa un IComparer<T> parametro.You can call an overload of the Sort method that includes an IComparer<T> parameter. Questo approccio è particolarmente utile se si desidera sviluppare una classe specializzata di ordinamento che è possibile ordinare gli oggetti in base a più criteri.This approach is especially useful if you want to develop a specialized sorting class that can sort objects based on multiple criteria.

    L'esempio seguente usa l'approccio grazie allo sviluppo di una classe personalizzata PersonComparer classe utilizzata per ordinare Person raccolte.The following example uses the approach by developing a custom PersonComparer class that is used to sort Person collections. Passa quindi un'istanza di questa classe per il List<T>.Sort(IComparer<T>) (metodo).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
    
  • Se non è possibile modificare il codice sorgente per il tipo si intende ordinare, è possibile creare un Comparison<T> delegato per eseguire l'ordinamento.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 firma del delegato èThe delegate signature is

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

    L'esempio seguente usa l'approccio definendo un PersonComparison metodo corrispondente il Comparison<T> firma del delegato.The following example uses the approach by defining a PersonComparison method that matches the Comparison<T> delegate signature. Passa quindi questo delegato per il List<T>.Sort(Comparison<T>) (metodo).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
    

Esegue il cast di un oggetto Nullable<T > null al relativo tipo sottostanteCasting a Nullable<T> that is null to its underlying type

Il tentativo di eseguire il cast di un Nullable<T> valore che rappresenta null al relativo tipo sottostante genera un' InvalidOperationException eccezione e visualizza il messaggio di errore "oggetto Nullable deve avere un valore.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.

Nell'esempio seguente genera un InvalidOperationException eccezione quando tenta di eseguire l'iterazione di una matrice che include un Nullable(Of Integer) valore.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()

Per evitare l'eccezione:To prevent the exception:

Nell'esempio seguente esegue entrambe le operazioni da evitare il InvalidOperationException eccezione.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

Chiamare un metodo Enumerable su una raccolta vuotaCalling a System.Linq.Enumerable method on an empty collection

Il Enumerable.Aggregate, Enumerable.Average, Enumerable.First, Enumerable.Last, Enumerable.Max, Enumerable.Min, Enumerable.Single, e Enumerable.SingleOrDefault metodi eseguono operazioni in una sequenza e restituiscono un singolo risultato.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. Alcuni overload di questi metodi generano un' InvalidOperationException eccezione quando la sequenza è vuota, mentre altri overload restituiscono null.Some overloads of these methods throw an InvalidOperationException exception when the sequence is empty, while other overloads return null. Il Enumerable.SingleOrDefault metodo genera inoltre un InvalidOperationException eccezione quando la sequenza contiene più di un elemento.The Enumerable.SingleOrDefault method also throws an InvalidOperationException exception when the sequence contains more than one element.

Nota

La maggior parte dei metodi che generano un InvalidOperationException eccezione sono overload.Most of the methods that throw an InvalidOperationException exception are overloads. Assicurarsi di aver compreso il comportamento dell'overload scelto.Be sure that you understand the behavior of the overload that you choose.

La tabella seguente elenca i messaggi di eccezione dal InvalidOperationException generati da chiamate ad alcuni oggetti di eccezione System.Linq.Enumerable metodi.The following table lists the exception messages from the InvalidOperationException exception objects thrown by calls to some System.Linq.Enumerable methods.

MetodoMethod MessaggioMessage
Aggregate
Average
Last
Max
Min
Sequenza non contiene elementiSequence contains no elements
First La sequenza non contiene alcun elemento corrispondenteSequence contains no matching element
Single
SingleOrDefault
La sequenza contiene più di un elemento corrispondaSequence contains more than one matching element

Come eliminare o gestire l'eccezione dipende dal presupposto dell'applicazione e il metodo specifico da chiamare.How you eliminate or handle the exception depends on your application's assumptions and on the particular method you call.

  • Quando si deliberatamente chiama uno di questi metodi senza verificare la presenza di una sequenza vuota, così facendo si presuppone che la sequenza non sia vuota e che una sequenza vuota sia un'occorrenza imprevista.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. In questo caso, rilevare o rigenerare l'eccezione è appropriato.In this case, catching or rethrowing the exception is appropriate .

  • Se l'impossibilità di verificare la presenza di una sequenza vuota è stata accidentale, è possibile chiamare uno degli overload del Enumerable.Any overload per determinare se una sequenza contiene elementi.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.

    Suggerimento

    La chiamata di Enumerable.Any<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) metodo prima di generare una sequenza può migliorare le prestazioni se l'elaborazione dei dati potrebbero contenere un numero elevato di elementi o se l'operazione che genera la sequenza è onerosa.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.

  • Se è stato chiamato un metodo, ad esempio Enumerable.First, Enumerable.Last, o Enumerable.Single, è possibile sostituirlo con un metodo alternativo, ad esempio Enumerable.FirstOrDefault, Enumerable.LastOrDefault, o Enumerable.SingleOrDefault, che restituisce un valore predefinito anziché da un membro della sequenza.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.

Gli esempi forniscono ulteriori dettagli.The examples provide additional detail.

L'esempio seguente usa il Enumerable.Average metodo per calcolare la media di una sequenza i cui valori sono superiori a 4.The following example uses the Enumerable.Average method to compute the average of a sequence whose values are greater than 4. Poiché nessun valore della matrice originale di superare i 4, nessun valore sono inclusi nella sequenza e il metodo genera un InvalidOperationException eccezione.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'eccezione può essere eliminata chiamando il Any metodo per determinare se la sequenza contiene elementi prima di chiamare il metodo che elabora la sequenza, come illustrato nell'esempio seguente.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.

Il Enumerable.First metodo restituisce il primo elemento in una sequenza o il primo elemento in una sequenza che soddisfa una condizione specificata.The Enumerable.First method returns the first item in a sequence or the first element in a sequence that satisfies a specified condition. Se la sequenza è vuota e pertanto non ha un primo elemento, viene generata un' InvalidOperationException eccezione.If the sequence is empty and therefore does not have a first element, it throws an InvalidOperationException exception.

Nell'esempio seguente, il Enumerable.First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) metodo genera un InvalidOperationException eccezione perché l'array di dbQueryResults non contiene un elemento maggiore di 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()

È possibile chiamare il Enumerable.FirstOrDefault invece del metodo Enumerable.First per restituire un oggetto specificato o il valore predefinito.You can call the Enumerable.FirstOrDefault method instead of Enumerable.First to return a specified or default value. Se il metodo non viene trovato un primo elemento nella sequenza, restituisce il valore predefinito per tale tipo di dati.If the method does not find a first element in the sequence, it returns the default value for that data type. Il valore predefinito è null per un tipo riferimento, zero per un tipo di dati numerici, e DateTime.MinValue per il DateTime tipo.The default value is null for a reference type, zero for a numeric data type, and DateTime.MinValue for the DateTime type.

Nota

Il valore restituito dall'interpretazione il Enumerable.FirstOrDefault metodo spesso è ulteriormente complicato dal fatto che il valore predefinito del tipo può essere un valore valido nella sequenza.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. In questo caso, è una chiamata di Enumerable.Any metodo per determinare se la sequenza dispone di membri validi prima di chiamare il Enumerable.First (metodo).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'esempio seguente chiama il Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) metodo per impedire la InvalidOperationException eccezione generata nell'esempio precedente.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.

Chiamare il metodo Enumerable o SingleOrDefault su una sequenza senza un elementoCalling Enumerable.Single or Enumerable.SingleOrDefault on a sequence without one element

Il Enumerable.Single metodo restituisce l'unico elemento di una sequenza o l'unico elemento di una sequenza che soddisfa una condizione specificata.The Enumerable.Single method returns the only element of a sequence, or the only element of a sequence that meets a specified condition. Se non esistono elementi nella sequenza oppure se è presente più di un elemento, il metodo genera un InvalidOperationException eccezione.If there are no elements in the sequence, or if there is more than one element , the method throws an InvalidOperationException exception.

È possibile usare il Enumerable.SingleOrDefault per restituire un valore predefinito anziché generare un'eccezione quando la sequenza non contiene elementi.You can use the Enumerable.SingleOrDefault method to return a default value instead of throwing an exception when the sequence contains no elements. Tuttavia, il Enumerable.SingleOrDefault metodo genera comunque un InvalidOperationException eccezione quando la sequenza contiene più di un elemento.However, the Enumerable.SingleOrDefault method still throws an InvalidOperationException exception when the sequence contains more than one element.

La tabella seguente elenca i messaggi di eccezione dal InvalidOperationException generati da chiamate agli oggetti di eccezione la Enumerable.Single e Enumerable.SingleOrDefault metodi.The following table lists the exception messages from the InvalidOperationException exception objects thrown by calls to the Enumerable.Single and Enumerable.SingleOrDefault methods.

MetodoMethod MessaggioMessage
Single La sequenza non contiene alcun elemento corrispondenteSequence contains no matching element
Single
SingleOrDefault
La sequenza contiene più di un elemento corrispondaSequence contains more than one matching element

Nell'esempio seguente, la chiamata ai Enumerable.Single metodo genera un InvalidOperationException eccezione perché la sequenza non dispone di un elemento maggiore di 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()

Nell'esempio seguente prova a impedire il InvalidOperationException eccezione generata quando una sequenza è vuota, chiamare invece il Enumerable.SingleOrDefault (metodo).The following example attempts to prevent the InvalidOperationException exception thrown when a sequence is empty by instead calling the Enumerable.SingleOrDefault method. Tuttavia, poiché questa sequenza restituisce più elementi il cui valore è maggiore di 2, genera inoltre un InvalidOperationException eccezione.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()

La chiamata di Enumerable.Single metodo presuppone che una sequenza o la sequenza che soddisfa i criteri specificati contiene un solo elemento.Calling the Enumerable.Single method assumes that either a sequence or the sequence that meets specified criteria contains only one element. Enumerable.SingleOrDefault si presuppone che una sequenza con zero o un risultato, ma non oltre.Enumerable.SingleOrDefault assumes a sequence with zero or one result, but no more. Se questa ipotesi è intenzionale da parte dell'utente e non vengono soddisfatte queste condizioni, la rigenerazione o il rilevamento risultante InvalidOperationException appropriato.If this assumption is a deliberate one on your part and these conditions are not met, rethrowing or catching the resulting InvalidOperationException is appropriate. In caso contrario, o se si prevede che si verificherà le condizioni non valide con una certa frequenza, è consigliabile usare un altro Enumerable metodo, ad esempio FirstOrDefault o 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.

Accesso al campo dinamico tra domini delle applicazioniDynamic cross-application domain field access

Il OpCodes.Ldflda Microsoft intermediate language (MSIL) istruzione genera un InvalidOperationException eccezione se l'oggetto che contiene il campo cui si sta tentando di recuperare l'indirizzo non è presente all'interno del dominio applicazione in cui viene eseguito il codice.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'indirizzo di un campo è accessibile solo dal dominio dell'applicazione in cui si trova.The address of a field can only be accessed from the application domain in which it resides.

Generare un'eccezione InvalidOperationExceptionThrowing an InvalidOperationException exception

È necessario generare un InvalidOperationException eccezioni solo quando lo stato dell'oggetto per qualche motivo non supporta una particolare chiamata al metodo.You should throw an InvalidOperationException exception only when the state of your object for some reason does not support a particular method call. Vale a dire, la chiamata al metodo è valida in alcune circostanze o contesti, ma non è valida in altri casi.That is, the method call is valid in some circumstances or contexts, but is invalid in others.

Se l'errore nella chiamata al metodo è argomenti non validi, quindi ArgumentException o una delle relative classi derivate ArgumentNullException o ArgumentOutOfRangeException, invece deve essere generata.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.

Informazioni di vario tipoMiscellaneous information

InvalidOperationException utilizza COR_E_INVALIDOPERATION HRESULT, che ha il valore 0x80131509.InvalidOperationException uses the HRESULT COR_E_INVALIDOPERATION, which has the value 0x80131509.

Per un elenco di valori di proprietà iniziali per un'istanza di InvalidOperationException, vedere il InvalidOperationException costruttori.For a list of initial property values for an instance of InvalidOperationException, see the InvalidOperationException constructors.

Costruttori

InvalidOperationException() InvalidOperationException() InvalidOperationException() InvalidOperationException()

Inizializza una nuova istanza della classe InvalidOperationException.Initializes a new instance of the InvalidOperationException class.

InvalidOperationException(SerializationInfo, StreamingContext) InvalidOperationException(SerializationInfo, StreamingContext) InvalidOperationException(SerializationInfo, StreamingContext) InvalidOperationException(SerializationInfo, StreamingContext)

Inizializza una nuova istanza della classe InvalidOperationException con dati serializzati.Initializes a new instance of the InvalidOperationException class with serialized data.

InvalidOperationException(String) InvalidOperationException(String) InvalidOperationException(String) InvalidOperationException(String)

Inizializza una nuova istanza della classe InvalidOperationException con un messaggio di errore specificato.Initializes a new instance of the InvalidOperationException class with a specified error message.

InvalidOperationException(String, Exception) InvalidOperationException(String, Exception) InvalidOperationException(String, Exception) InvalidOperationException(String, Exception)

Inizializza una nuova istanza della classe InvalidOperationException con un messaggio di errore specificato e un riferimento all'eccezione interna che è la causa dell'eccezione corrente.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.

Proprietà

Data Data Data Data

Ottiene una raccolta di coppie chiave-valore che fornisce informazioni aggiuntive definite dall'utente relative all'eccezione.Gets a collection of key/value pairs that provide additional user-defined information about the exception.

(Inherited from Exception)
HelpLink HelpLink HelpLink HelpLink

Ottiene o imposta un collegamento al file della Guida associato all'eccezione.Gets or sets a link to the help file associated with this exception.

(Inherited from Exception)
HResult HResult HResult HResult

Ottiene o imposta HRESULT, un valore numerico codificato che viene assegnato a un'eccezione specifica.Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.

(Inherited from Exception)
InnerException InnerException InnerException InnerException

Ottiene l'istanza di Exception che ha causato l'eccezione corrente.Gets the Exception instance that caused the current exception.

(Inherited from Exception)
Message Message Message Message

Ottiene un messaggio che descrive l'eccezione corrente.Gets a message that describes the current exception.

(Inherited from Exception)
Source Source Source Source

Ottiene o imposta il nome dell'oggetto o dell'applicazione che ha generato l'errore.Gets or sets the name of the application or the object that causes the error.

(Inherited from Exception)
StackTrace StackTrace StackTrace StackTrace

Ottiene una rappresentazione di stringa dei frame immediati nello stack di chiamate.Gets a string representation of the immediate frames on the call stack.

(Inherited from Exception)
TargetSite TargetSite TargetSite TargetSite

Ottiene il metodo che genera l'eccezione corrente.Gets the method that throws the current exception.

(Inherited from Exception)

Metodi

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetBaseException() GetBaseException() GetBaseException() GetBaseException()

Se utilizzato come metodo di override in una classe derivata, restituisce l'Exception che è la causa radice di una o più eccezioni successive.When overridden in a derived class, returns the Exception that is the root cause of one or more subsequent exceptions.

(Inherited from Exception)
GetHashCode() GetHashCode() GetHashCode() GetHashCode()

Funge da funzione hash predefinita.Serves as the default hash function.

(Inherited from Object)
GetObjectData(SerializationInfo, StreamingContext) GetObjectData(SerializationInfo, StreamingContext) GetObjectData(SerializationInfo, StreamingContext) GetObjectData(SerializationInfo, StreamingContext)

Quando l'override viene eseguito in una classe derivata, imposta il controllo SerializationInfo per la colonna.When overridden in a derived class, sets the SerializationInfo with information about the exception.

(Inherited from Exception)
GetType() GetType() GetType() GetType()

Ottiene il tipo di runtime dell'istanza corrente.Gets the runtime type of the current instance.

(Inherited from Exception)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.Creates a shallow copy of the current Object.

(Inherited from Object)
ToString() ToString() ToString() ToString()

Crea e restituisce una rappresentazione di stringa dell'eccezione corrente.Creates and returns a string representation of the current exception.

(Inherited from Exception)

Eventi

SerializeObjectState SerializeObjectState SerializeObjectState SerializeObjectState

Si verifica quando un'eccezione viene serializzata per creare un oggetto di stato eccezione contenente i dati serializzati relativi all'eccezione.Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.

(Inherited from Exception)

Si applica a

Vedi anche