C# Language Les meilleures pratiques


Exemple

Cheatsheet

FAIRE Ne pas
Contrôle du flux avec des instructions de contrôle Contrôle des flux avec des exceptions
Suivre les exceptions ignorées (absorbées) en se connectant Ignorer l'exception
Répétez l'exception en utilisant throw Re-jeter une exception - throw new ArgumentNullException() ou throw ex
Lancer des exceptions système prédéfinies Jeter des exceptions personnalisées similaires aux exceptions système prédéfinies
Jeter une exception personnalisée / prédéfinie si elle est cruciale pour la logique de l'application Lancer des exceptions personnalisées / prédéfinies pour indiquer un avertissement dans le flux
Catch exceptions que vous souhaitez gérer Attraper toutes les exceptions

NE PAS gérer la logique métier avec des exceptions.

Le contrôle de flux ne doit PAS être effectué par des exceptions. Utilisez plutôt des instructions conditionnelles. Si un contrôle peut être effectué avec l'instruction if-else clairement, n'utilisez pas les exceptions car cela réduit la lisibilité et les performances.

Considérez l'extrait suivant de Mr. Bad Practices:

// This is a snippet example for DO NOT
object myObject;
void DoingSomethingWithMyObject()
{
    Console.WriteLine(myObject.ToString());
}

Lorsque l'exécution atteint Console.WriteLine(myObject.ToString()); l'application lancera une exception NullReferenceException. M. Bad Practices s'est rendu compte que myObject était nul et a modifié son extrait pour intercepter et gérer NullReferenceException :

// This is a snippet example for DO NOT
object myObject;
void DoingSomethingWithMyObject()
{
    try
    {
        Console.WriteLine(myObject.ToString());
    }
    catch(NullReferenceException ex)
    {
        // Hmmm, if I create a new instance of object and assign it to myObject:
        myObject = new object();
        // Nice, now I can continue to work with myObject
        DoSomethingElseWithMyObject();
    }
}

Comme l'extrait de myObject précédent ne couvre que la logique d'exception, que dois-je faire si myObject n'est pas nul à ce stade? Où devrais-je couvrir cette partie de la logique? Juste après Console.WriteLine(myObject.ToString()); ? Qu'en est-il après le try...catch block?

Qu'en est-il de Mr. Best Practices? Comment va-t-il gérer ça?

// This is a snippet example for DO
object myObject;
void DoingSomethingWithMyObject()
{
    if(myObject == null)
        myObject = new object();
    
    // When execution reaches this point, we are sure that myObject is not null
    DoSomethingElseWithMyObject();
}

M. Best Practices a atteint la même logique avec moins de code et une logique claire et compréhensible.

NE PAS rejeter les exceptions

Relancer les exceptions est coûteux. Cela a un impact négatif sur les performances. Pour le code qui échoue régulièrement, vous pouvez utiliser des modèles de conception pour minimiser les problèmes de performances. Cette rubrique décrit deux modèles de conception utiles lorsque des exceptions peuvent avoir un impact significatif sur les performances.

NE PAS absorber les exceptions sans enregistrement

try
{
    //Some code that might throw an exception
}
catch(Exception ex)
{
    //empty catch block, bad practice
}

Ne jamais avaler les exceptions. Ignorer les exceptions sauvera ce moment mais créera un chaos pour la maintenabilité plus tard. Lors de la journalisation des exceptions, vous devez toujours consigner l'instance d'exception afin que la trace complète de la pile soit consignée et non uniquement le message d'exception.

try
{
    //Some code that might throw an exception
}
catch(NullException ex)
{
    LogManager.Log(ex.ToString());
}

Ne pas intercepter les exceptions que vous ne pouvez pas gérer

De nombreuses ressources, telles que celle-ci , vous invitent fortement à réfléchir aux raisons pour lesquelles vous attrapez une exception à l'endroit où vous la capturez. Vous ne devriez attraper une exception que si vous pouvez la gérer à cet endroit. Si vous pouvez faire quelque chose pour atténuer le problème, par exemple essayer un autre algorithme, vous connecter à une base de données de sauvegarde, essayer un autre nom de fichier, attendre 30 secondes et réessayer ou avertir un administrateur, vous pouvez détecter l'erreur. S'il n'y a rien que vous puissiez faire de manière plausible et raisonnable, il suffit de "laisser aller" et de laisser l'exception être traitée à un niveau supérieur. Si l'exception est suffisamment catastrophique et qu'il n'y a pas d'autre option raisonnable que le blocage complet du programme en raison de la gravité du problème, laissez-le tomber en panne.

try
{
    //Try to save the data to the main database.
}
catch(SqlException ex)
{
    //Try to save the data to the alternative database.
}
//If anything other than a SqlException is thrown, there is nothing we can do here. Let the exception bubble up to a level where it can be handled.