Question

Si je mets des blocs catch vides pour mon code C #, ça va être un équivalent "On Error Resume Next" de VB.NET déclaration.

try
{
    C# code;
}

catch(exception)
{
}

La raison pour laquelle je pose cette question parce que je dois convertir un code VB.NET en C #, et l'ancien code a ~ 200 « On Error Resume Next » déclarations bien que je me sers d'un try {} catch {} bon dans mon nouveau code, mais est il y a une meilleure alternative?

Était-ce utile?

La solution

J'ai trouvé que les programmeurs de code VB souvent jonchées de nombreuses déclarations On Error Resume Next par habitude (de mauvais). Ma suggestion serait de commencer par pas exceptions réprimées, et voir ce qui en fait des pauses. Il ne peut y avoir autant de questions que vous le pensez. A l'inverse, plus vous pouvez faire le test de régression, mieux; il peut y avoir des cas limites qui ne fonctionnent que lorsque des erreurs sont ignorées.

En fin de compte, vous devez décider d'une stratégie de gestion des erreurs, que ce soit déroulement grâce à l'intérieur de blocs try / catch ou des erreurs de laisser percoler à un gestionnaire de niveau supérieur (les deux stratégies ont leurs utilisations).

Si vous finissez par avoir à supprimer certaines exceptions à respecter un délai, au moins log ces exceptions afin que le prochain développeur qui travaille sur votre code ne soit pas brûlé par un try/catch vide.

Autres conseils

Bien que parfois cela est acceptable, généralement il indique une odeur de code. Si vous êtes 100% sûr de vouloir avaler l'exception qui a eu lieu, vous pouvez le faire de la façon dont vous avez, mais en général si une exception vous est jeté devrait faire quelque chose .

En général, vous pouvez obtenir le même résultat avec le code bien conçu. Si vous rencontrez actuellement une erreur spécifique, ajoutez à votre question, mais si vous demandez juste par curiosité, non il n'y a pas d'équivalent, et qui est une bonne chose.

Non, ce n'est pas la même chose.

Lors de l'utilisation On Error Resume Next, VB sauterait à la ligne suivante si une erreur se produit. Avec try / catch, l'exécution passe au bloc catch si une erreur (exception) se produit.

Vous devez analyser les déclarations de On Error Resume Next un par un et voir ce que leur but. Certains peuvent être simplement le code bâclée, mais il y a des raisons valables pour On Error Resume Next dans le code Visual Basic 6.0.

Voici quelques exemples de pourquoi utiliser On Error Resume Next dans le code Visual Basic 6.0:

  • Pour vérifier si une donnée clé existe dans une collection Visual Basic 6.0. La seule façon de le faire est d'accéder à l'élément par clé, et gérer l'erreur qui se pose si la clé n'existe pas. Lors de la conversion à .NET, vous pouvez le remplacer par un chèque de l'existence de la clé.

  • l'analyse d'une chaîne à un nombre entier. Dans .NET, vous pouvez utiliser TryParse .

Bien que On Error Resume Next est certainement abusé de plus qu'il est utilisé légitimement, il y a des endroits où il serait utile même dans VB.NET.

Soit un programme qui attribue des valeurs à un grand nombre de propriétés Excel, telles que les valeurs par défaut à tous les paramètres de l'imprimante - il y a des paramètres de l'imprimante zillion dans Excel. Les versions ultérieures d'Excel pourraient avoir des propriétés qui versions antérieures ne prennent pas en charge, et ce n'est pas trivial de comprendre ceux qui sont pris en charge dans chaque version. Le programme devrait attribuer une valeur si la propriété existe, mais ignorer la propriété si une ancienne version d'Excel est utilisée.

La « bonne » façon de le faire avec VB.NET serait de déterminer les propriétés de l'imprimante sont pris en charge par chaque version d'Excel, lisez la version en cours d'utilisation, et d'attribuer uniquement à des propriétés qui sont mises en œuvre dans cette version. Cela nécessiterait beaucoup de recherches et un code, le tout pour peu d'avantages. On Error Resume Next serait une solution plus pratique.

Et, malheureusement, je suis confronté à ce problème maintenant avec précision. La solution que je vais essayer d'écrire est un sous-programme qui attribue une seule valeur à une autre, sans tenir compte des erreurs. Je vais appeler cette subrouting en place de chaque instruction d'affectation. Pas trop lamentables, mais pas si grand soit.

"On Error Resume Next" permet de "Gestion des erreurs en ligne", qui est l'erreur de niveau expert en manipulation VB. Le concept est à la ligne d'erreurs de poignée par ligne, soit effectuer une action basée sur l'erreur ou ignorer l'erreur lorsque bénéfique - code, mais en cours d'exécution dans la séquence dans laquelle il est écrit et non en utilisant des sauts code.

Malheureusement, beaucoup de novices utilisé « On Error Resume Next » pour cacher leur soit manque de capacité ou de la paresse de ceux qui utilisent leurs applications en ignorant toutes les erreurs. Try/catch est la gestion des erreurs de niveau bloc, ce qui dans le monde pre-.NET était intermédiaire par la conception et la mise en œuvre.

Le problème avec « On Error Resume Next » dans VB.NET est qu'il charge l'objet err sur chaque ligne de l'exécution du code et est donc plus lent que try/catch. Je suis un peu inquiet que ce forum vérifié et promu une réponse inepte qui a fait l'aide On Error Resume Next est une mauvaise habitude et la litière code. Ce forum est un C #; devrait-il être utilisé pour vraiment programmeurs C # pour prendre des photos à une autre langue qu'ils sont peu familiarisés avec?

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

Il dit que les programmeurs intermédiaires C # avec aucune expérience réelle VB ne devrait pas essayer de garder C # dumbed et fonctionnalité limitée en raison de leur dédain bizarre pour une autre langue « Microsoft Net », Considérez le code suivant:

//-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 le fichier XML a généralement une valeur pour Field3 mais parfois pas; Je vais faire une erreur ennuyeux que la table ne contient pas le champ. Je pourrais prendre soin d'un moins si elle n'est pas parce qu'il les données nécessaires. Dans ce cas, ON Error Resume Next me permettrait d'ignorer l'erreur et je ne voudrais pas avoir à coder autour de chaque ligne de code définissant les variables de contrôle de l'existence de la table, la ligne et la combinaison de la colonne avec Contient des méthodes. Ceci est un petit exemple; Je pourrais tirer en milliers de table, colonne, combinaisons de lignes de gros fichiers. En outre, supposons ici que les variables de chaîne doivent être remplis de cette façon. Ceci est du code unhandled et il y aura des problèmes.

Considérons un VB.NET et ON Error Resume Next Mise en œuvre:

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()

Dans le code ci-dessus, il était seulement nécessaire pour traiter une condition d'erreur possible; même si il y avait deux erreurs avant la troisième a été traitée. besoins de développement RAD On Error Resume Next. C # est mon choix de langues, mais il est pas autant une langue RAD comme VB pour de nombreuses raisons. J'espère que tous les programmeurs se rendent compte que plusieurs langues principales (à savoir C) juste courir et ne pas l'exécution de l'arrêt sur les erreurs non gérées; c'est le travail des développeurs de vérifier pour eux où ils jugent nécessaires. On Error Resume Next est la chose la plus proche de ce paradigme dans le monde Microsoft.

Heureusement, .NET ne donne beaucoup de choix avancés pour gérer ces situations; J'éludé la Contains. Ainsi, en C #, vous devez renforcer votre niveau de connaissance de la langue et vous correctement, selon la spécification du langage C #, le travail autour de ces questions. Considérons une solution pour traiter un grand bloc de lignes répétitives de code qui pourrait contenir une erreur de distance de jet gênant:

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);
            } 

Bien que dans un bloc try / catch, la fonction lambda vérifie l'existence de chaque combinaison table, ligne, colonne qui est tirée de l'ensemble de données a été complétée de manière dynamique par le xml. Cela pourrait être vérifié ligne par ligne, mais il faudrait beaucoup de code excès (ici nous avons la même quantité d'exécuter le code, mais beaucoup moins du code écrit pour maintenir). Cela pourrait malheureusement être considéré comme une autre mauvaise pratique des « fonctions d'une ligne. » Je casse cette règle dans le cas des lambdas et des fonctions anonymes.

Depuis .NET offre tant de façons de vérifier l'état des objets; On Error Resume Next est pas aussi vital pour les experts VB comme ilétait avant .NET mais toujours agréable d'avoir autour; surtout quand vous codez quelque chose qui serait une perte de temps pour ne pas le code rapide et sale. Pour vous Java convertis à C #; rejoindre le monde Microsoft et cesser de prétendre que si 10000 Java intermédiaires et programmeurs C # disent, que ça doit être vrai parce que si un haut niveau de Microsoft Guru (comme l'un de ceux qui a créé le langage VB et .NET) vous contredit évidemment leur développement .NET de lui-même, il est faux et vous ridiculiser. Je veux toutes les fonctionnalités que je peux obtenir en C # et VB et F # et toute autre langue que je dois utiliser. C # est élégant mais VB est plus évolué en raison il est beaucoup plus d'ancienneté, mais ils ont tous deux faire la « chose même » et utiliser les mêmes objets. Apprenez à la fois bien ou s'il vous plaît résister à commenter soit dans les conversations de comparaison; il est nauséabonde pour ceux d'entre nous qui ont été autour depuis les années nonante de milieu en utilisant des technologies Microsoft à un niveau élevé.

Utilisation « On Error Resume Next » n'est pas une bonne idée pour le traitement des erreurs (bien sûr, ceci est mon opinion personnelle, mais il semble que la plupart des développeurs d'accord avec moi si). Comme d'autres gars vous conseille dans les messages précédents, l'utilisation Try...Catch...Finally (que ce soit dans VB.NET ou C # ).

Il est très intelligent option pour la gestion des erreurs, mais il vous permettra également de ne rien faire avec l'erreur (un bloc catch vide) :) Je vous suggère de mettre chaque ligne de code (ce qui peut provoquer une erreur) dans Try...Catch Block séparé, de sorte que vous auriez la possibilité de faire ce que vous voulez si une erreur se produit. gars heureux codage:)

Le bon remplacement pour .NET « lors de la reprise erreur suivante » est l'utilisation de méthodes Try___. Dans Visual Basic 6.0, pour savoir si une clé existait dans une collection, il fallait soit chercher la collection manuellement (lent horriblement), ou bien essayer d'indexer et de piéger toute erreur qui a eu lieu si elle était pas là. Dans VB.NET, l'objet Dictionary (qui est une version améliorée de l'ancienne collection) prend en charge une méthode TryGetValue, qui indiquera si oui ou non la tentative d'obtenir la valeur a réussi, sans provoquer une erreur si elle ne l'a pas. Un certain nombre d'autres objets .NET supporte des fonctionnalités similaires. Il existe quelques méthodes qui devraient avoir « essayer » équivalents mais ne pas (par exemple, Control.BeginInvoke), mais il y a suffisamment peu d'entre eux qui les envelopper individuellement dans un Try/Catch est pas trop onéreux.

J'arrive à penser les gens qui ont inventé « On Error Resume Next » a eu quelque chose à l'esprit quand ils l'ont créé. La réponse à votre question ne serait pas, il n'y a rien équivalent à cette construction en C #. Nous avons en C # et .Net beaucoup de fonctions qui sont si avides de soins et d'attention, il devient fatiguant après un certain temps pour répondre à un « comportement exceptionnel » de tout le monde. Quand presque tout peut jeter une exception le mot lui-même perd sa signification un peu. Vous êtes à l'intérieur d'une itération et que devez-vous faire si quelques milliers de millions d'articles se trouvent être exceptionnel? Resume Next pourrait être l'une des réponses pratiques.

Comme été dit par Medora @ Tim, vous devez faire un effort pour éviter d'utiliser cette approche lors du codage. Cependant, dans certains cas, il est utile, et il est possible d'imiter un tel comportement. Voici une fonction et un exemple de l'utiliser. (Notez que certains éléments de code ont été écrits en 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();
    } 

Exemple, au lieu 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 { }

vous pouvez:

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

Je suis un vieux chapeau à VB6. Tout d'abord une courte leçon ...

Il y a des raisons d'utiliser On Error Resume Next. La plupart du temps pour une meilleure lisibilité. En VB6 vous avez deux façons de mettre en œuvre le piégeage d'erreur. Vous pouvez utiliser une "ligne" On Error Resume Next comme celui-ci.

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

Ou, vous pouvez voir ceci:

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  

Mais dans l'ancien code VB6 vous verrez probablement aussi ce ...

Sub PerformThis
On Error Resume Next

End Sub

Quelle que soit il est assez simple de convertir ces cas dans Try Catch ... Si vous avez besoin de couler une utilisation d'erreur d'une « ligne » rapide à la recherche On Error Resume Next faire tout ce ..

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

Vous pouvez également augmenter la prise d'essai à la routine d'appel, en encapsulant le code dans un sous-programme ... Donc, si vous avez besoin de faire couler le sous-programme tout le faire ...

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

Faites ceci dans le cas où PerformAction sous-programme () contient un On Error Resume Next en haut du code, utilisez Try Catch dans le sous-programme appelant

Bonne chance ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top