Pregunta

Si pongo bloques de captura vacíos para mi código C#, ¿va a ser un equivalente para la declaración "On Error Reano de VB.NET"?

try
{
    C# code;
}

catch(exception)
{
}

La razón por la que estoy preguntando esto es porque tengo que convertir un código VB.NET en C#, y el código anterior tiene ~ 200 "En las declaraciones de Error Reano". try {} catch {} En mi nuevo código, pero ¿hay una mejor alternativa?

¿Fue útil?

Solución

Descubrí que los programadores de VB a menudo cubrían el código con muchos On Error Resume Next declaraciones fuera del hábito (malo). Mi sugerencia sería comenzar con no Excepciones suprimidas y ver lo que realmente se rompe. Puede que no haya tantos problemas como pienses. Por el contrario, cuantas más pruebas de regresión pueda hacer, mejor; Puede haber algunos casos de borde que solo funcionan cuando se ignoran los errores.

En última instancia, debe decidir sobre una estrategia de manejo de errores, ya sea que sea elegante relajarse dentro de muchos bloques de try/captación, o dejar que los errores se filtren a un controlador de nivel superior (ambas estrategias tienen sus usos).

Si termina teniendo que suprimir algunas excepciones para cumplir con una fecha límite, por lo menos Registre esas excepciones para que el próximo desarrollador que trabaje en su código no sea quemado por un vacío try/catch.

Otros consejos

Aunque a veces esto es aceptable, generalmente indica un olor a código. Si está 100% seguro de que desea tragarse la excepción que ha ocurrido, puede hacerlo de la manera que lo ha hecho, pero en general si se le arroja una excepción. debería hacer alguna cosa.

En general, puede lograr el mismo resultado con un código bien diseñado. Si actualmente está experimentando un error específico, agrégalo a su pregunta, pero si está pidiendo por curiosidad, no, no hay un equivalente, y eso es algo bueno.

No, no es lo mismo.

Cuando se usa el currículum de error, VB saltaría a la siguiente línea si se produce un error. Con Try/Catch, la ejecución salta al bloque de captura si se produce un error (excepción).

Necesitas analizar el On Error Resume Next Declaraciones una por una y ver cuál es su propósito. Algunos pueden ser simplemente un código descuidado, pero hay razones válidas para On Error Resume Next en el código Visual Basic 6.0.

Algunos ejemplos de por qué usar On Error Resume Next en el código de Visual Basic 6.0:

  • Para verificar si existe una clave dada en una colección Visual Basic 6.0. La única forma de hacerlo es acceder al elemento por clave y manejar el error que se plantea si la clave no existe. Al convertir a .NET, puede reemplazar esto mediante una verificación de la existencia de la clave.

  • Analizar una cadena a un entero. En .net puedes usar Tryparse.

A pesar de que On Error Resume Next Ciertamente se abusa más de lo que se usa legítimamente, hay lugares donde sería útil incluso en VB.NET.

Considere un programa que asigna valores a una gran cantidad de propiedades de Excel, como los valores predeterminados a todos los parámetros de la impresora: hay un trillón de parámetros de impresora en Excel. Las versiones posteriores de Excel pueden tener propiedades que las versiones anteriores no admiten, y no es trivial descubrir cuáles son compatibles con cada versión. El programa debe asignar un valor si la propiedad existe, pero ignora la propiedad si se utiliza una versión anterior de Excel.

La forma "correcta" de hacer esto con VB.NET sería determinar qué propiedades de la impresora son compatibles con cada versión de Excel, leer la versión en uso y solo asignar a propiedades que se implementan en esa versión. Eso requeriría mucha investigación y algún código, todo para poco beneficio. On Error Resume Next sería una solución más práctica.

Y, desafortunadamente, me enfrento precisamente a este problema ahora. La solución que voy a probar es escribir una subrutina que solo asigne un valor a otro, ignorando los errores. Llamaré a esto subrutando en lugar de cada declaración de tarea. No es demasiado terable, pero tampoco tan bien.

"On Error Reano Next" permite "manejo de errores en línea", que es el manejo de errores de nivel de experto en VB. El concepto es manejar los errores de línea por línea, ya sea realizar una acción basada en el error o ignorar el error cuando es beneficioso, pero ejecutar el código en la secuencia en la que está escrito y no usar saltos de código.

Desafortunadamente, muchos novatos usaron "en reanudación de errores a continuación" para ocultar su falta de capacidad o por pereza de aquellos que usan sus aplicaciones ignorando todos los errores. Try/catch Es el manejo de errores de nivel de bloque, que en el mundo pre-.net fue intermedio por diseño e implementación.

El problema con "EN ERROR ERRUME SIGUIENTE" en VB.NET es que carga el objeto ERR en cada línea de código de ejecución y, por lo tanto, es más lento que try/catch. Estoy un poco alarmado de que este foro revisó y promovió una respuesta inanida que afirmó usar el currículum de error a continuación es un mal hábito y una basura de código. Este es un foro C#; ¿Debería usarse realmente para que los programadores de C# tomen tomas en otro idioma en el que no están bien versados?

https://msdn.microsoft.com/en-us/library/aa242093(v=vs.60).aspx

Se dice que los programadores intermedios de C# sin experiencia en VB real no deberían intentar mantener a C# maldita y a Funcion Limited debido a su extraño desdén por otro lenguaje "Microsoft Net", considere el siguiente código:

//-Pull xml from file and dynamically create a dataset.
 string strXML = File.ReadAllText(@"SomeFilePath.xml");
 StringReader sr = new StringReader(strXML);
 DataSet dsXML = new DataSet();
 dsXML.ReadXml(sr);

string str1 = dsXML.Tables["Table1"].Rows[0]["Field1"].ToString();
string str2 = dsXML.Tables["Table2"].Rows[0]["Field2"].ToStrin();
string str3 = dsXML.Tables["Table3"].Rows[0]["Field3"].ToStrin();
string str4 = dsXML.Tables["Table4"].Rows[0]["Field4"].ToString();
string str5 = dsXML.Tables["Table5"].Rows[0]["Field5"].ToString();

Si el XML generalmente tiene un valor para Field3 pero a veces no; Voy a recibir un error molesto de que la tabla no contiene el campo. Podría importarme menos si no es así porque no son datos requeridos. En este caso, en el currículum de error a continuación me permitiría ignorar el error y no tendría que codificar alrededor de cada línea de código configurando las variables verificando la existencia de la combinación de la tabla, la fila y la columna con los métodos contenidos. Este es un pequeño ejemplo; Podría extraer miles de combinaciones de tabla, columna y fila de archivos grandes. Además, suponga aquí que las variables de cadena deben estar pobladas de esta manera. Este es un código no controlado y habrá problemas.

Considere una implementación VB.NET y de error de error:

On Error Resume Next

        'Pull Xml from file And dynamically create a dataset.
        Dim strXML As String = File.ReadAllText("SomeFilePath.xml")
        Dim srXmL As StringReader = New StringReader(strXML)
        Dim dsXML As DataSet = New DataSet()
        dsXML.ReadXml(srXmL)

        'Any error above will kill processing. I can ignore the first two errors and only need to worry about dataset loading the XML.
        If Err.Number <> 0 Then
            MsgBox(Err.Number & Space(1) & Err.Description)
            Exit Sub 'Or Function
        End If

        Dim str1 As String = dsXML.Tables("Table1").Rows(1)("Field1").ToString()
        Dim str2 As String = dsXML.Tables("Table2").Rows(2)("Field2").ToString()
        Dim str3 As String = dsXML.Tables("Table3").Rows(3)("Field3").ToString()
        Dim str4 As String = dsXML.Tables("Table4").Rows(4)("Field4").ToString()

En el código anterior, solo era necesario manejar una posible condición de error; a pesar de que hubo dos errores antes de que se manejara el tercero. El desarrollo de RAD necesita en el currículum de error a continuación. C# es mi elección de idiomas, pero no es tanto un lenguaje rad como VB por muchas razones. Espero que todos los programadores se den cuenta de que varios lenguajes principales (es decir, C) simplemente se ejecutan y no detienen la ejecución de errores no controlados; Es el trabajo de los desarrolladores verificarlos donde piensen necesarios. En el currículum de error, el siguiente es lo más cercano a ese paradigma en el mundo de Microsoft.

Afortunadamente, .NET da muchas opciones avanzadas para manejar estas situaciones; Elegí a los contenidos. Entonces, en C#, debe reforzar su nivel de conocimiento del idioma y usted correctamente, de acuerdo con la especificación del lenguaje C#, trabaja en torno a tales problemas. Considere una solución para manejar un gran bloque de líneas repetitivas de código que podrían contener un error molesto de tiros:

try
            {
                if (!File.Exists(@"SomeFilePath.xml")) { throw new Exception("XML File Was Not Found!"); }
                string strXML = File.ReadAllText(@"SomeFilePath.xml");
                StringReader sr = new StringReader(strXML);
                DataSet dsXML = new DataSet();
                dsXML.ReadXml(sr);

                Func<string, string, int, string> GetFieldValue = (t, f, x) => (dsXML.Tables[t].Columns.Contains(f) && dsXML.Tables[t].Rows.Count >= x + 1) ? dsXML.Tables[t].Rows[x][f].ToString() : "";

                //-Load data from dynamically created dataset into strings.
                string str1 = GetFieldValue("Table1", "Field1", 0);
                string str2 = GetFieldValue("Table2", "Field2", 0);
                string str3 = GetFieldValue("Table3", "Field3", 0);
                //-And so on.

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            } 

Aunque en un bloque Try/Catch, la función Lambda está verificando la existencia de cada tabla, combinación de fila y columna que se extrae del conjunto de datos que fue poblada dinámicamente por el XML. Esto podría verificarse por línea, pero requeriría un montón de código de exceso (aquí tenemos la misma cantidad de código de ejecución pero mucho menos código escrito para mantener). Lamentablemente, esto podría considerarse otra mala práctica de "funciones de una línea". Rompo esa regla en el caso de lambdas y funciones anónimas.

Dado que .NET ofrece muchas formas de verificar el estado de los objetos; El currículum vitae de error siguiente no es tan vital para los expertos en VB como antes de .NET, pero aún así es bueno tenerlo en torno; Especialmente cuando está codificando algo que sería una pérdida de tiempo para no codificar rápido y sucio. Para ti, Java se convierte en C#; Únase al mundo de Microsoft y deje de fingir que si 10000 programadores intermedios de Java y C# lo dicen, entonces debe ser verdad Su desarrollo de .NET mismo, es falso y te ves tonto. Quiero toda la funcionalidad que pueda obtener en C# y VB y F# y cualquier otro idioma que necesite usar. C# es elegante, pero VB está más evolucionado debido a que es una tenencia mucho más larga, pero ambos hacen lo mismo "y usan los mismos objetos. Aprenda bien o por favor resistirme a comentar cualquiera de los dos en las conversaciones de comparación; Es nauseabundo para aquellos de nosotros que hemos existido desde mediados de los noventa usando Microsoft Technologies a un alto nivel.

Usar "EN Error Reano Siguiente" no es una buena idea para el manejo de errores (por supuesto, esta es mi opinión personal, pero parece que la mayoría de los desarrolladores están de acuerdo conmigo). Como otros tipos te aconsejaron en publicaciones anteriores, usa Try...Catch...Finally (ya sea en Vb.net o C#).

Esta es una opción muy inteligente para el manejo de errores, pero también le permitirá no hacer nada con el error (un bloque de captura vacío) :) Le sugiero que coloque cada línea de código (que puede causar error) en separación Try...Catch Block, para que tenga la oportunidad de hacer lo que quiera si ocurre un error. Feliz codificación chicos :)

El reemplazo de .NET adecuado para "Error de error Siguiente" es el uso de los métodos Try___. En Visual Basic 6.0, para averiguar si existía una llave en una colección, uno tenía que buscar la colección manualmente (horriblemente lenta), o de lo contrario intentar indexarla y atrapar cualquier error que ocurriera si no estaba allí. En VB.NET, el objeto del diccionario (que es una versión mejorada de la colección anterior) admite un TryGetValue Método, que indicará si el intento de obtener el valor tiene éxito, sin causar un error si no lo hizo. Varios otros objetos .NET admiten una funcionalidad similar. Hay algunos métodos que deberían tener equivalentes de "prueba" pero no (por ejemplo, Control.BeginInvoke), pero hay suficientes pocos que los envuelven individualmente en un Try/Catch no es demasiado oneroso.

Creo que esas personas que inventaron "en el reanudación de errores a continuación" tenían algo en mente cuando lo crearon. La respuesta a su pregunta sería no, no hay nada equivalente a esta construcción en C#. Tenemos en C# y .net muchas funciones que tienen tanta hambre de cuidado y atención que se agita después de un tiempo para atender el "comportamiento excepcional" de todos. Cuando casi todo puede lanzar una excepción, la palabra en sí pierde su significado. Estás dentro de una iteración y ¿qué debes hacer si pocos miles de los millones de artículos son excepcionales? El currículum siguiente podría ser una de las respuestas útiles.

Como ha dicho @tim Medora, debe hacer un esfuerzo para evitar usar dicho enfoque al codificar. Sin embargo, en algunos casos es útil, y es posible emular dicho comportamiento. Aquí hay una función y un ejemplo de usarla. (Tenga en cuenta que algunos elementos de código se escribieron usando C#6)

    /// <summary>
    /// Execute each of the specified action, and if the action is failed, go and executes the next action.
    /// </summary>
    /// <param name="actions">The actions.</param>
    public static void OnErrorResumeNext(params Action[] actions)
    {
        OnErrorResumeNext(actions: actions, returnExceptions: false);
    }

    /// <summary>
    /// Execute each of the specified action, and if the action is failed go and executes the next action.
    /// </summary>
    /// <param name="returnExceptions">if set to <c>true</c> return list of exceptions that were thrown by the actions that were executed.</param>
    /// <param name="putNullWhenNoExceptionIsThrown">if set to <c>true</c> and <paramref name="returnExceptions"/> is also <c>true</c>, put <c>null</c> value in the returned list of exceptions for each action that did not threw an exception.</param>
    /// <param name="actions">The actions.</param>
    /// <returns>List of exceptions that were thrown when executing the actions.</returns>
    /// <remarks>
    /// If you set <paramref name="returnExceptions"/> to <c>true</c>, it is possible to get exception thrown when trying to add exception to the list. 
    /// Note that this exception is not handled!
    /// </remarks>
    public static Exception[] OnErrorResumeNext(bool returnExceptions = false, bool putNullWhenNoExceptionIsThrown = false, params Action[] actions)
    {
        var exceptions = returnExceptions ? new Collections.GenericArrayList<Exception>() : null;
        foreach (var action in actions)
        {
            Exception exp = null;
            try { action.Invoke(); }
            catch (Exception ex) { if(returnExceptions) { exp = ex; } }

            if (exp != null || putNullWhenNoExceptionIsThrown) { exceptions.Add(exp); }
        }
        return exceptions?.ToArray();
    } 

Ejemplo, en lugar de:

        var a = 19;
        var b = 0;
        var d = 0;
        try { a = a / b; } catch { }
        try { d = a + 5 / b; } catch { }
        try { d = (a + 5) / (b + 1); } catch { }

puedes:

            var a = 19;
            var b = 0;
            var d = 0;
            OnErrorResumeNext(
                () =>{a = a / b;},
                () =>{d = a + 5 / b;},
                () =>{d = (a + 5) / (b + 1);}
            );

Soy un sombrero viejo en VB6. Primero una breve lección ...

Hay razones para usar en el currículum de error a continuación. Principalmente para la legibilidad. En VB6 tiene dos formas de implementar la captura de errores. Puede usar un currículum de error "en línea" en el siguiente currículum como este.

On Error Resume Next
<something that may throw an error>
If Err.Number <> 0 Then
   <do something about this specific line of code>
   Err.Clear()
End If

O puede ver esto:

Sub DoSomething

   On Error Goto Handler1
   <do something that causes an error>

   On Error Goto Handler2
   <do something that may cause an error>

   Exit Sub

   Handler1:
   <log error or something>
   Resume Next

   Handler2:
   <log error or something>
   Resume Next

End Sub  

Pero en el antiguo código VB6, probablemente también vea esto ...

Sub PerformThis
On Error Resume Next

End Sub

Independientemente, es bastante sencillo convertir estos casos en trate de captura ... si necesita hundir un error, use un rápido "en línea" que busque un currículum de error a continuación, solo haga esto ...

try { _objectinfo.Add(_object.attribute1); } catch (Exception _e) { }

También puede elevar la trisión de la rutina de llamadas, encapsulando el código en una subrutina ... así que si necesita hundir toda la subrutina, haga esto ...

try { PerformAction(); } catch (Exception _e) { }

Haga esto en el caso en que la subrutina performAction () contiene un currículum de error en la parte superior del código, use la captura de prueba en la subrutina de llamada

Buena suerte...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top