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 : Exception
public ref class InvalidOperationException : SystemException
public class InvalidOperationException : Exception
public class InvalidOperationException : SystemException
[System.Serializable]
public class InvalidOperationException : SystemException
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class InvalidOperationException : SystemException
type InvalidOperationException = class
inherit Exception
type InvalidOperationException = class
inherit SystemException
[<System.Serializable>]
type InvalidOperationException = class
inherit SystemException
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type InvalidOperationException = class
inherit SystemException
Public Class InvalidOperationException
Inherits Exception
Public Class InvalidOperationException
Inherits SystemException
- Herencia
- Herencia
- 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, una InvalidOperationException excepción la producen métodos como:For example, an InvalidOperationException exception is thrown by methods such as:
IEnumerator.MoveNext Si los objetos de una colección se modifican después de crear el enumerador.IEnumerator.MoveNext if objects of a collection are modified after the enumerator is created. Para obtener más información, vea cambiar una colección mientras se recorre en iteración.For more information, see Changing a collection while iterating it.
ResourceSet.GetString Si el conjunto de recursos se cierra antes de que se realice la llamada al método.ResourceSet.GetString if the resource set is closed before the method call is made.
XContainer.Add, si el objeto u objetos que se van a agregar daría como resultado un documento XML estructurado incorrectamente.XContainer.Add, if the object or objects to be added would result in an incorrectly structured XML document.
Un método que intenta manipular la interfaz de usuario desde un subproceso que no es el subproceso principal o de interfaz de usuario.A method that attempts to manipulate the UI from a thread that is not the main or UI thread.
Importante
Dado que la InvalidOperationException excepción se puede iniciar en una gran variedad de circunstancias, es importante leer el mensaje de excepción devuelto por la Message propiedad.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
Conversión de un valor null que acepta valores NULL < > a 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 InvalidOperationException se produce la 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, normalmente, la excepción resulta de un error del desarrollador y la InvalidOperationException excepción se puede anticipar y evitar.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 embargo,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). InvalidOperationExceptionSe produce una excepción al intentar tener acceso a un elemento de la interfaz de usuario desde un subproceso distinto del subproceso de la 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 Dispatcher.CheckAccess método 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 la interfaz de usuario y defalse
lo contrario.It returnstrue
if the method is running on the UI thread andfalse
otherwise. Llame a una de las sobrecargas del Dispatcher.Invoke método 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 CoreDispatcher.HasThreadAccess propiedad 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 CoreDispatcher.RunAsync método 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 Control.InvokeRequired propiedad 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 Control.Invoke método 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 namedtextBox1
. En una aplicación Windows Forms, debe establecer su Multiline propiedad entrue
.In a Windows Forms app, you should set its Multiline property totrue
.Un control de botón denominado
threadExampleBtn
.A button control namedthreadExampleBtn
. En el ejemplo se proporciona un controlador,ThreadsExampleBtn_Click
, para elClick
evento del botón.The example provides a handler,ThreadsExampleBtn_Click
, for the button'sClick
event.
En cada caso, el threadExampleBtn_Click
controlador de eventos llama al DoSomeWork
método dos veces.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 InvalidOperationException excepción.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 DoSomeWork
método 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 DoSomeWork
método 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 DoSomeWork
método 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 foreach
instrucción de C# o la For Each
instrucción 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 InvalidOperationException excepción 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 excepción InvalidOperationException con la primera llamada al List<T>.Add método.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
for
instrucción en lugar deforeach
oFor Each
.If elements must be added to the collection while iterating it, you can iterate it by index using thefor
statement instead offoreach
orFor 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 mediante el uso de un contador dentro del bucle que salga del bucle correctamente, recorriendo hacia atrás, de
Count
-1 a 0, o, como hace 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, fromCount
- 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 Array.Sort(Array) método o el List<T>.Sort() método, normalmente requieren que al menos uno de los objetos que se van a ordenar implemente la IComparable<T> IComparable interfaz o.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 InvalidOperationException excepción.If not, the collection or array cannot be sorted, and the method throws an InvalidOperationException exception. En el ejemplo siguiente se define una Person
clase, se almacenan dos Person
objetos en un List<T> objeto 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 List<T>.Sort() método produce una excepción 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 la IComparable<T> IComparable interfaz o.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 IComparable<T>.CompareTo método o 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 IComparable<T> implementación para la
Person
clase.The following example uses this approach to provide an IComparable<T> implementation for thePerson
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}", other.LastName, other.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}", other.LastName, other.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 IComparer<T> interfaz.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
Sort
método que incluye un IComparer<T> parámetro.You can call an overload of theSort
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
PersonComparer
clase personalizada que se utiliza para ordenarPerson
colecciones.The following example uses the approach by developing a customPersonComparer
class that is used to sortPerson
collections. A continuación, pasa una instancia de esta clase al List<T>.Sort(IComparer<T>) método.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
PersonComparison
método que coincide con la Comparison<T> firma del delegado.The following example uses the approach by defining aPersonComparison
method that matches the Comparison<T> delegate signature. A continuación, pasa este delegado al List<T>.Sort(Comparison<T>) método.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 valor null <T> que sea NULL a su tipo subyacenteCasting a Nullable<T> that is null to its underlying type
Si se intenta convertir un Nullable<T> valor que está null
en su tipo subyacente, se produce una InvalidOperationException excepción y se muestra el mensaje de error, " el objeto 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 InvalidOperationException excepción al intentar iterar una matriz que incluye un Nullable(Of Integer)
valor.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:
Utilice la Nullable<T>.HasValue propiedad para seleccionar solo los elementos que no son
null
.Use the Nullable<T>.HasValue property to select only those elements that are notnull
.Llame a una de las Nullable<T>.GetValueOrDefault sobrecargas para proporcionar un valor predeterminado para un
null
valor.Call one of the Nullable<T>.GetValueOrDefault overloads to provide a default value for anull
value.
En el ejemplo siguiente se hace para evitar la 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 Enumerable.Aggregate Enumerable.Average métodos,, Enumerable.First , Enumerable.Last , Enumerable.Max , Enumerable.Min , Enumerable.Single y 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 InvalidOperationException excepción 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 Enumerable.SingleOrDefault método también produce una InvalidOperationException excepción 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 InvalidOperationException excepción son las 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 InvalidOperationException objetos de excepción que se inician mediante llamadas a algunos System.Linq.Enumerable métodos.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.
Cuando se llama deliberadamente a uno de estos métodos sin comprobar si hay una secuencia vacía, se asume que la secuencia no está vacía y que una secuencia vacía es una ocurrencia inesperada.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. En este caso, es adecuado detectar o volver a producir la excepción.In this case, catching or rethrowing the exception is appropriate .
Si el error de comprobación de una secuencia vacía era involuntaria, puede llamar a una de las sobrecargas de la Enumerable.Any sobrecarga para determinar si una secuencia contiene elementos.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.
Sugerencia
Llamar al Enumerable.Any<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) método antes de generar una secuencia puede mejorar el rendimiento si los datos que se van a procesar pueden contener un gran número de elementos o si la operación que genera la secuencia es costosa.Calling the Enumerable.Any<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) method before generating a sequence can improve performance if the data to be processed might contain a large number of elements or if operation that generates the sequence is expensive.
Si ha llamado a un método como Enumerable.First , Enumerable.Last o Enumerable.Single , puede sustituir un método alternativo, como Enumerable.FirstOrDefault , Enumerable.LastOrDefault o Enumerable.SingleOrDefault , que devuelve un valor predeterminado en lugar de un miembro de la secuencia.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.
Los ejemplos proporcionan detalles adicionales.The examples provide additional detail.
En el ejemplo siguiente se usa el Enumerable.Average método 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 InvalidOperationException excepción.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 Any método para determinar si la secuencia contiene algún elemento 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 Enumerable.First método 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, se produce una InvalidOperationException excepción.If the sequence is empty and therefore does not have a first element, it throws an InvalidOperationException exception.
En el ejemplo siguiente, el Enumerable.First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) método produce una InvalidOperationException excepción 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 Enumerable.FirstOrDefault método 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 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
Interpretar el valor devuelto por el Enumerable.FirstOrDefault método 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 Enumerable.Any método para determinar si la secuencia tiene miembros válidos antes de llamar al Enumerable.First método.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 Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>) método para evitar la excepción que se InvalidOperationException produce 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 Enumerable.Single método 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 InvalidOperationException excepción.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 Enumerable.SingleOrDefault método 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 Enumerable.SingleOrDefault método todavía produce una InvalidOperationException excepción 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 InvalidOperationException objetos de excepción que se inician mediante llamadas a los Enumerable.Single Enumerable.SingleOrDefault métodos y.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 Enumerable.Single método produce una InvalidOperationException excepción 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 InvalidOperationException se produzca la excepción cuando una secuencia está vacía mediante una llamada al Enumerable.SingleOrDefault método.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 InvalidOperationException excepción.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 Enumerable.Single método 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 supone 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 resultado InvalidOperationException .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 Enumerable método, 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 OpCodes.Ldflda instrucción máquina del lenguaje intermedio de Microsoft (MSIL) produce una InvalidOperationException excepción 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 ejecuta 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 InvalidOperationException excepción solo cuando el estado del objeto por alguna razón no admita una llamada de método determinada.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, ArgumentException ArgumentNullException ArgumentOutOfRangeException se debería iniciar o una de sus clases derivadas, o.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 utiliza 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 la 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 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) |