InvalidOperationException Clase

Definición

Excepción que se produce cuando una llamada a un método no es válida para el estado actual del objeto.The exception that is thrown when a method call is invalid for the object's current state.

public ref class InvalidOperationException : SystemException
public class InvalidOperationException : SystemException
[System.Serializable]
public class InvalidOperationException : SystemException
[System.Runtime.InteropServices.ComVisible(true)]
[System.Serializable]
public class InvalidOperationException : SystemException
type InvalidOperationException = class
    inherit SystemException
Public Class InvalidOperationException
Inherits SystemException
Herencia
InvalidOperationException
Herencia
InvalidOperationException
Derivado
Atributos

Comentarios

InvalidOperationException se utiliza en casos en los que el error al invocar un método se debe a motivos distintos a los argumentos no válidos.InvalidOperationException is used in cases when the failure to invoke a method is caused by reasons other than invalid arguments. Normalmente, se produce cuando el estado de un objeto no admite la llamada al método.Typically, it is thrown when the state of an object cannot support the method call. Por ejemplo InvalidOperationException, los métodos, como:For example, an InvalidOperationException exception is thrown by methods such as:

Importante

Dado que la InvalidOperationException excepción puede producirse en una amplia variedad de circunstancias, es importante leer el mensaje de excepción devuelto por la propiedad 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.

En esta sección:In this section:

Algunas causas comunes de las excepciones InvalidOperationException Some common causes of InvalidOperationException exceptions
Actualizar un subproceso de interfaz de usuario desde un subproceso que no es de interfaz de usuarioUpdating a UI thread from a non-UI thread
Cambiar una colección mientras se recorre en iteraciónChanging a collection while iterating it
Ordenar una matriz o colección cuyos objetos no se pueden compararSorting an array or collection whose objects cannot be compared
Convertir un> de<t que acepta valores NULL que es null para su tipo subyacente Casting a Nullable<T> that is null to its underlying type
Llamar a un método System. Linq. Enumerable en una colección vacíaCalling a System.Linq.Enumerable method on an empty collection
Llamar a Enumerable. single o Enumerable. SingleOrDefault en una secuencia sin un elementoCalling Enumerable.Single or Enumerable.SingleOrDefault on a sequence without one element
Acceso dinámico a campos de dominio de aplicación cruzadoDynamic cross-application domain field access
Producir una excepción InvalidOperationExceptionThrowing an InvalidOperationException exception
Información diversaMiscellaneous information

Algunas causas comunes de las excepciones InvalidOperationExceptionSome common causes of InvalidOperationException exceptions

En las secciones siguientes se muestra cómo se producen en una aplicación algunos casos comunes en los que en InvalidOperationException excepción.The following sections show how some common cases in which in InvalidOperationException exception is thrown in an app. La forma de controlar el problema depende de la situación específica.How you handle the issue depends on the specific situation. Sin embargo, lo más habitual es que la excepción resulte de un error del desarrollador y se pueda anticipar y evitar la excepción InvalidOperationException.Most commonly, however, the exception results from developer error, and the InvalidOperationException exception can be anticipated and avoided.

Actualizar un subproceso de interfaz de usuario desde un subproceso que no es de interfaz de usuarioUpdating a UI thread from a non-UI thread

A menudo, los subprocesos de trabajo se utilizan para realizar algún trabajo en segundo plano que implique la recopilación de datos que se mostrarán en la interfaz de usuario de una aplicación.Often, worker threads are used to perform some background work that involves gathering data to be displayed in an application's user interface. Sin.However. la mayoría de los marcos de aplicaciones de GUI (interfaz gráfica de usuario) para el .NET Framework, como Windows Forms y Windows Presentation Foundation (WPF), permiten acceder a objetos GUI solo desde el subproceso que crea y administra la interfaz de usuario (el subproceso principal o de la interfaz de usuario).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). Se produce una InvalidOperationException al intentar tener acceso a un elemento de la interfaz de usuario desde un subproceso distinto del subproceso de interfaz de usuario.An InvalidOperationException is thrown when you try to access a UI element from a thread other than the UI thread. En la tabla siguiente se muestra el texto del mensaje de excepción.The text of the exception message is shown in the following table.

Tipo de aplicaciónApplication Type MensajeMessage
Aplicación WPFWPF app El subproceso que realiza la llamada no puede tener acceso a este objeto porque un subproceso diferente lo posee.The calling thread cannot access this object because a different thread owns it.
Aplicación para UWPUWP app La aplicación llamó a una interfaz que se serializó para un subproceso diferente.The application called an interface that was marshaled for a different thread.
Windows Forms aplicaciónWindows Forms app Operación entre subprocesos no válida: se tiene acceso al control ' TextBox1 ' desde un subproceso distinto del subproceso en el que se creó.Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on.

Los marcos de interfaz de usuario para el .NET Framework implementan un patrón de distribuidor que incluye un método para comprobar si se está ejecutando una llamada a un miembro de un elemento de la interfaz de usuario en el subproceso de la interfaz de usuario y otros métodos para programar la llamada en el subproceso de la interfaz de usuario: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:

  • En las aplicaciones de WPF, llame al método Dispatcher.CheckAccess para determinar si un método se está ejecutando en un subproceso que no es de interfaz de usuario.In WPF apps, call the Dispatcher.CheckAccess method to determine if a method is running on a non-UI thread. Devuelve true si el método se está ejecutando en el subproceso de interfaz de usuario y false de lo contrario.It returns true if the method is running on the UI thread and false otherwise. Llame a una de las sobrecargas del método Dispatcher.Invoke para programar la llamada en el subproceso de la interfaz de usuario.Call one of the overloads of the Dispatcher.Invoke method to schedule the call on the UI thread.

  • En aplicaciones UWP, Compruebe la propiedad CoreDispatcher.HasThreadAccess para determinar si un método se está ejecutando en un subproceso que no es de interfaz de usuario.In UWP apps, check the CoreDispatcher.HasThreadAccess property to determine if a method is running on a non-UI thread. Llame al método CoreDispatcher.RunAsync para ejecutar un delegado que actualice el subproceso de la interfaz de usuario.Call the CoreDispatcher.RunAsync method to execute a delegate that updates the UI thread.

  • En Windows Forms aplicaciones, use la propiedad Control.InvokeRequired para determinar si un método se está ejecutando en un subproceso que no es de interfaz de usuario.In Windows Forms apps, use the Control.InvokeRequired property to determine if a method is running on a non-UI thread. Llame a una de las sobrecargas del método Control.Invoke para ejecutar un delegado que actualice el subproceso de la interfaz de usuario.Call one of the overloads of the Control.Invoke method to execute a delegate that updates the UI thread.

En los siguientes ejemplos se muestra la InvalidOperationException excepción que se produce al intentar actualizar un elemento de la interfaz de usuario desde un subproceso distinto del subproceso que lo creó.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. Cada ejemplo requiere la creación de dos controles:Each example requires that you create two controls:

  • Un control de cuadro de texto denominado textBox1.A text box control named textBox1. En una aplicación Windows Forms, debe establecer su propiedad Multiline en true.In a Windows Forms app, you should set its Multiline property to true.

  • Control de botón denominado threadExampleBtn.A button control named threadExampleBtn. En el ejemplo se proporciona un controlador, ThreadsExampleBtn_Click, para el evento de Click del botón.The example provides a handler, ThreadsExampleBtn_Click, for the button's Click event.

En cada caso, el controlador de eventos threadExampleBtn_Click llama dos veces al método DoSomeWork.In each case, the threadExampleBtn_Click event handler calls the DoSomeWork method twice. La primera llamada se ejecuta sincrónicamente y se realiza correctamente.The first call runs synchronously and succeeds. Pero la segunda llamada, dado que se ejecuta de forma asincrónica en un subproceso de grupo de subprocesos, intenta actualizar la interfaz de usuario desde un subproceso que no es de interfaz de usuario.But the second call, because it runs asynchronously on a thread pool thread, attempts to update the UI from a non-UI thread. Esto produce una excepción InvalidOperationException.This results in a InvalidOperationException exception.

Aplicaciones de WPF y 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 siguiente versión del método DoSomeWork elimina la excepción en una aplicación 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 siguiente versión del método DoSomeWork elimina la excepción en una aplicación de 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

Aplicaciones de 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 siguiente versión del método DoSomeWork elimina la excepción en una aplicación 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

Cambiar una colección mientras se recorre en iteraciónChanging a collection while iterating it

La instrucción foreach en C# la instrucción o For Each de Visual Basic se utiliza para iterar los miembros de una colección y para leer o modificar sus elementos individuales.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. Sin embargo, no se puede usar para agregar o quitar elementos de la colección.However, it can't be used to add or remove items from the collection. Al hacerlo, se produce una excepción de InvalidOperationException con un mensaje similar a "se modificó la colección". es posible que la operación de enumeración no se ejecute."Doing this throws an InvalidOperationException exception with a message that is similar to, "Collection was modified; enumeration operation may not execute."

En el ejemplo siguiente se recorre en iteración una colección de enteros intenta agregar el cuadrado de cada entero a la colección.The following example iterates a collection of integers attempts to add the square of each integer to the collection. En el ejemplo se produce una InvalidOperationException con la primera llamada al método 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()

Puede eliminar la excepción de una de estas dos maneras, en función de la lógica de la aplicación:You can eliminate the exception in one of two ways, depending on your application logic:

  • Si los elementos se deben agregar a la colección mientras se recorre en iteración, se puede iterar por índice mediante la instrucción for en lugar de 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. En el ejemplo siguiente se usa la instrucción for para agregar el cuadrado de los números de la colección a la colección.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
    

    Tenga en cuenta que debe establecer el número de iteraciones antes de recorrer en iteración la colección utilizando un contador dentro del bucle que salga del bucle correctamente, recorriendo hacia atrás, desde Count-1 hasta 0, o, como se hace en el ejemplo, asignando el número de elementos de la matriz a una variable y usando el valor para establecer el límite superior del bucle.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. De lo contrario, si se agrega un elemento a la colección en cada iteración, se produce un bucle sin fin.Otherwise, if an element is added to the collection on every iteration, an endless loop results.

  • Si no es necesario agregar elementos a la colección mientras se recorre en iteración, puede almacenar los elementos que se van a agregar en una colección temporal que se agrega al recorrer en iteración la colección.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. En el ejemplo siguiente se usa este enfoque para agregar el cuadrado de los números de una colección a una colección temporal y, a continuación, combinar las colecciones en un objeto de matriz único.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
    

Ordenar una matriz o colección cuyos objetos no se pueden compararSorting an array or collection whose objects cannot be compared

Los métodos de ordenación de uso general, como el método Array.Sort(Array) o el método List<T>.Sort(), normalmente requieren que al menos uno de los objetos que se van a ordenar implemente el IComparable<T> o la interfaz de 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 no, no se puede ordenar la colección o matriz y el método produce una excepción InvalidOperationException.If not, the collection or array cannot be sorted, and the method throws an InvalidOperationException exception. En el ejemplo siguiente se define una clase Person, se almacenan dos objetos Person en un objeto List<T> genérico y se intenta ordenarlos.The following example defines a Person class, stores two Person objects in a generic List<T> object, and attempts to sort them. Como muestra la salida del ejemplo, la llamada al método List<T>.Sort() produce una 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()

Puede eliminar la excepción de tres maneras:You can eliminate the exception in any of three ways:

  • Si puede ser el propietario del tipo que está intentando ordenar (es decir, si controla su código fuente), puede modificarlo para implementar el IComparable<T> o la interfaz 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. Para ello, es necesario implementar el método IComparable<T>.CompareTo o el CompareTo.This requires that you implement either the IComparable<T>.CompareTo or the CompareTo method. Agregar una implementación de interfaz a un tipo existente no es un cambio importante.Adding an interface implementation to an existing type is not a breaking change.

    En el ejemplo siguiente se usa este enfoque para proporcionar una implementación de IComparable<T> para la clase Person.The following example uses this approach to provide an IComparable<T> implementation for the Person class. Todavía puede llamar al método de ordenación general de la colección o matriz y, como muestra el resultado del ejemplo, la colección se ordena correctamente.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 no puede modificar el código fuente del tipo que está intentando ordenar, puede definir una clase de ordenación especial que implemente la interfaz 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. Puede llamar a una sobrecarga del método Sort que incluye un parámetro IComparer<T>.You can call an overload of the Sort method that includes an IComparer<T> parameter. Este enfoque es especialmente útil si desea desarrollar una clase de ordenación especializada que pueda ordenar los objetos en función de varios criterios.This approach is especially useful if you want to develop a specialized sorting class that can sort objects based on multiple criteria.

    En el ejemplo siguiente se utiliza el enfoque mediante el desarrollo de una clase de PersonComparer personalizada que se usa para ordenar Person colecciones.The following example uses the approach by developing a custom PersonComparer class that is used to sort Person collections. A continuación, pasa una instancia de esta clase al método 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 no puede modificar el código fuente del tipo que está intentando ordenar, puede crear un Comparison<T> delegado para realizar la ordenación.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 delegado esThe delegate signature is

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

    En el ejemplo siguiente se utiliza el enfoque definiendo un método PersonComparison que coincide con la firma del delegado Comparison<T>.The following example uses the approach by defining a PersonComparison method that matches the Comparison<T> delegate signature. A continuación, pasa este delegado al método 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
    

Convertir un > de<T que acepta valores NULL que es null para su tipo subyacenteCasting a Nullable<T> that is null to its underlying type

Si se intenta convertir un valor Nullable<T> que se null a su tipo subyacente, se produce una excepción InvalidOperationException y se muestra el mensaje de error "elobjeto que acepta valores NULL debe tener un valor.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.

En el ejemplo siguiente se produce una excepción InvalidOperationException cuando intenta recorrer en iteración una matriz que incluye un valor 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()

Para evitar la excepción:To prevent the exception:

En el ejemplo siguiente, se evitan las InvalidOperationException excepción.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

Llamar a un método System. Linq. Enumerable en una colección vacíaCalling a System.Linq.Enumerable method on an empty collection

Los métodos Enumerable.Aggregate, Enumerable.Average, Enumerable.First, Enumerable.Last, Enumerable.Max, Enumerable.Min, Enumerable.Singley Enumerable.SingleOrDefault realizan operaciones en una secuencia y devuelven un único resultado.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. Algunas sobrecargas de estos métodos producen una excepción InvalidOperationException cuando la secuencia está vacía, mientras que otras sobrecargas devuelven null.Some overloads of these methods throw an InvalidOperationException exception when the sequence is empty, while other overloads return null. El método Enumerable.SingleOrDefault también produce una excepción InvalidOperationException cuando la secuencia contiene más de un elemento.The Enumerable.SingleOrDefault method also throws an InvalidOperationException exception when the sequence contains more than one element.

Nota

La mayoría de los métodos que producen una excepción InvalidOperationException son sobrecargas.Most of the methods that throw an InvalidOperationException exception are overloads. Asegúrese de que comprende el comportamiento de la sobrecarga que elija.Be sure that you understand the behavior of the overload that you choose.

En la tabla siguiente se enumeran los mensajes de excepción de los objetos de excepción InvalidOperationException generados por llamadas a algunos métodos de 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étodoMethod MensajeMessage
Aggregate
Average
Last
Max
Min
La secuencia no contiene elementosSequence contains no elements
First La secuencia no contiene ningún elemento coincidenteSequence contains no matching element
Single
SingleOrDefault
La secuencia contiene más de un elemento coincidenteSequence contains more than one matching element

La forma de eliminar o controlar la excepción depende de las suposiciones de la aplicación y del método concreto al que llame.How you eliminate or handle the exception depends on your application's assumptions and on the particular method you call.

Los ejemplos proporcionan detalles adicionales.The examples provide additional detail.

En el ejemplo siguiente se usa el método Enumerable.Average para calcular el promedio de una secuencia cuyos valores son mayores que 4.The following example uses the Enumerable.Average method to compute the average of a sequence whose values are greater than 4. Dado que ningún valor de la matriz original es superior a 4, no se incluyen valores en la secuencia y el método produce una excepción 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()

La excepción se puede eliminar llamando al método Any para determinar si la secuencia contiene elementos antes de llamar al método que procesa la secuencia, como se muestra en el ejemplo siguiente.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.

El método Enumerable.First devuelve el primer elemento de una secuencia o el primer elemento de una secuencia que satisface una condición especificada.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 secuencia está vacía y, por tanto, no tiene un primer elemento, produce una excepción InvalidOperationException.If the sequence is empty and therefore does not have a first element, it throws an InvalidOperationException exception.

En el ejemplo siguiente, el método Enumerable.First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) produce una excepción InvalidOperationException porque la matriz dbQueryResults no contiene un elemento mayor que 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()

Puede llamar al método Enumerable.FirstOrDefault en lugar de Enumerable.First para devolver un valor especificado o predeterminado.You can call the Enumerable.FirstOrDefault method instead of Enumerable.First to return a specified or default value. Si el método no encuentra un primer elemento en la secuencia, devuelve el valor predeterminado para ese tipo de datos.If the method does not find a first element in the sequence, it returns the default value for that data type. El valor predeterminado es null para un tipo de referencia, cero para un tipo de datos numérico y DateTime.MinValue para el tipo de DateTime.The default value is null for a reference type, zero for a numeric data type, and DateTime.MinValue for the DateTime type.

Nota

Interpretar el valor devuelto por el método Enumerable.FirstOrDefault suele ser complicado por el hecho de que el valor predeterminado del tipo puede ser un valor válido en la secuencia.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. En este caso, se llama al método Enumerable.Any para determinar si la secuencia tiene miembros válidos antes de llamar al método 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.

En el ejemplo siguiente se llama al método Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) para evitar la excepción de InvalidOperationException producida en el ejemplo anterior.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.

Llamar a Enumerable. single o Enumerable. SingleOrDefault en una secuencia sin un elementoCalling Enumerable.Single or Enumerable.SingleOrDefault on a sequence without one element

El método Enumerable.Single devuelve el único elemento de una secuencia o el único elemento de una secuencia que cumple una condición especificada.The Enumerable.Single method returns the only element of a sequence, or the only element of a sequence that meets a specified condition. Si no hay elementos en la secuencia, o si hay más de un elemento, el método produce una excepción InvalidOperationException.If there are no elements in the sequence, or if there is more than one element , the method throws an InvalidOperationException exception.

Puede usar el método Enumerable.SingleOrDefault para devolver un valor predeterminado en lugar de producir una excepción cuando la secuencia no contiene elementos.You can use the Enumerable.SingleOrDefault method to return a default value instead of throwing an exception when the sequence contains no elements. Sin embargo, el método Enumerable.SingleOrDefault todavía produce una excepción InvalidOperationException cuando la secuencia contiene más de un elemento.However, the Enumerable.SingleOrDefault method still throws an InvalidOperationException exception when the sequence contains more than one element.

En la tabla siguiente se enumeran los mensajes de excepción de los objetos de excepción InvalidOperationException que se producen mediante llamadas a los métodos Enumerable.Single y 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étodoMethod MensajeMessage
Single La secuencia no contiene ningún elemento coincidenteSequence contains no matching element
Single
SingleOrDefault
La secuencia contiene más de un elemento coincidenteSequence contains more than one matching element

En el ejemplo siguiente, la llamada al método Enumerable.Single produce una excepción InvalidOperationException porque la secuencia no tiene un elemento mayor que 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()

En el ejemplo siguiente se intenta evitar que se produzca la excepción InvalidOperationException cuando una secuencia está vacía mediante una llamada al método Enumerable.SingleOrDefault.The following example attempts to prevent the InvalidOperationException exception thrown when a sequence is empty by instead calling the Enumerable.SingleOrDefault method. Sin embargo, dado que esta secuencia devuelve varios elementos cuyo valor es mayor que 2, también produce una excepción 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()

La llamada al método Enumerable.Single supone que una secuencia o la secuencia que cumple los criterios especificados solo contiene un elemento.Calling the Enumerable.Single method assumes that either a sequence or the sequence that meets specified criteria contains only one element. Enumerable.SingleOrDefault presupone una secuencia con cero o un resultado, pero no más.Enumerable.SingleOrDefault assumes a sequence with zero or one result, but no more. Si esta suposición es una de las partes deliberadas y no se cumplen estas condiciones, es adecuado volver a producir o detectar el InvalidOperationException resultante.If this assumption is a deliberate one on your part and these conditions are not met, rethrowing or catching the resulting InvalidOperationException is appropriate. De lo contrario, o si espera que se produzcan condiciones no válidas con cierta frecuencia, debería considerar la posibilidad de usar algún otro método de Enumerable, como 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.

Acceso dinámico a campos de dominio de aplicación cruzadoDynamic cross-application domain field access

La instrucción OpCodes.Ldflda lenguaje intermedio de Microsoft (MSIL) produce una excepción de InvalidOperationException si el objeto que contiene el campo cuya dirección está intentando recuperar no está dentro del dominio de aplicación en el que se está ejecutando el código.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. Solo se puede tener acceso a la dirección de un campo desde el dominio de aplicación en el que reside.The address of a field can only be accessed from the application domain in which it resides.

Producir una excepción InvalidOperationExceptionThrowing an InvalidOperationException exception

Debe iniciar una excepción InvalidOperationException solo cuando el estado del objeto por alguna razón no admita una llamada al método determinado.You should throw an InvalidOperationException exception only when the state of your object for some reason does not support a particular method call. Es decir, la llamada al método es válida en algunas circunstancias o contextos, pero no es válido en otros.That is, the method call is valid in some circumstances or contexts, but is invalid in others.

Si el error de invocación del método se debe a que los argumentos no son válidos, se debe iniciar en su lugar ArgumentException o una de sus clases derivadas, ArgumentNullException o ArgumentOutOfRangeException.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.

Información diversaMiscellaneous information

InvalidOperationException usa el COR_E_INVALIDOPERATION HRESULT, que tiene el valor 0x80131509.InvalidOperationException uses the HRESULT COR_E_INVALIDOPERATION, which has the value 0x80131509.

Para obtener una lista de valores de propiedad iniciales de una instancia de InvalidOperationException, consulte el InvalidOperationException constructores.For a list of initial property values for an instance of InvalidOperationException, see the InvalidOperationException constructors.

Constructores

InvalidOperationException()

Inicializa una nueva instancia de la clase InvalidOperationException.Initializes a new instance of the InvalidOperationException class.

InvalidOperationException(SerializationInfo, StreamingContext)

Inicializa una nueva instancia de la clase InvalidOperationException con datos serializados.Initializes a new instance of the InvalidOperationException class with serialized data.

InvalidOperationException(String)

Inicializa una nueva instancia de la clase InvalidOperationException con el mensaje de error especificado.Initializes a new instance of the InvalidOperationException class with a specified error message.

InvalidOperationException(String, Exception)

Inicializa una nueva instancia de la clase InvalidOperationException con el mensaje de error especificado y una referencia a la excepción interna que representa la causa de esta excepción.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.

Propiedades

Data

Obtiene una colección de pares clave/valor que proporciona información definida por el usuario adicional sobre la excepción.Gets a collection of key/value pairs that provide additional user-defined information about the exception.

(Heredado de Exception)
HelpLink

Obtiene o establece un vínculo al archivo de ayuda asociado a esta excepción.Gets or sets a link to the help file associated with this exception.

(Heredado de Exception)
HResult

Obtiene o establece HRESULT, un valor numérico codificado que se asigna a una excepción específica.Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception.

(Heredado de Exception)
InnerException

Obtiene la instancia Exception que produjo la excepción actual.Gets the Exception instance that caused the current exception.

(Heredado de Exception)
Message

Obtiene un mensaje que describe la excepción actual.Gets a message that describes the current exception.

(Heredado de Exception)
Source

Devuelve o establece el nombre de la aplicación o del objeto que generó el error.Gets or sets the name of the application or the object that causes the error.

(Heredado de Exception)
StackTrace

Obtiene una representación de cadena de los marcos inmediatos en la pila de llamadas.Gets a string representation of the immediate frames on the call stack.

(Heredado de Exception)
TargetSite

Obtiene el método que produjo la excepción actual.Gets the method that throws the current exception.

(Heredado de Exception)

Métodos

Equals(Object)

Determina si el objeto especificado es igual que el objeto actual.Determines whether the specified object is equal to the current object.

(Heredado de Object)
GetBaseException()

Cuando se invalida en una clase derivada, devuelve la clase Exception que representa la causa principal de una o más excepciones posteriores.When overridden in a derived class, returns the Exception that is the root cause of one or more subsequent exceptions.

(Heredado de Exception)
GetHashCode()

Sirve como función hash predeterminada.Serves as the default hash function.

(Heredado de Object)
GetObjectData(SerializationInfo, StreamingContext)

Cuando se invalida en una clase derivada, establece SerializationInfo con información sobre la excepción.When overridden in a derived class, sets the SerializationInfo with information about the exception.

(Heredado de Exception)
GetType()

Obtiene el tipo de tiempo de ejecución de la instancia actual.Gets the runtime type of the current instance.

(Heredado de Exception)
MemberwiseClone()

Crea una copia superficial del objeto Object actual.Creates a shallow copy of the current Object.

(Heredado de Object)
ToString()

Crea y devuelve una representación de cadena de la excepción actual.Creates and returns a string representation of the current exception.

(Heredado de Exception)

Eventos

SerializeObjectState

Ocurre cuando una excepción se serializa para crear un objeto de estado de excepción que contenga datos serializados sobre la excepción.Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.

(Heredado de Exception)

Se aplica a

Consulte también: