Archive

Posts Tagged ‘CSharp’

Using using…

02/08/2015 5 commentaires

Mois d’aout, vacances, coding, sport, mais aussi Windows 10, VS 2015 et aussi un peu de temps pour creuser quelques idées testées dans l’année.

IMG_4479

Ici une idée très simple pour sécuriser un code encore plus simple mais qui nous embête régulièrement.

Il y a quelque années (oups 8 ans…) j’avais profité des méthodes anonymes de C# pour tester un moyen de factoriser du code “englobant” tel qu’avec les instructions try…catch.

Vous pouvez encore trouver ici mon billet relatif de l’époque.

On peut appliquer cette solution à tout type de code ayant une logique d’ouverture puis de fermeture: try…catch, début et fin de transaction, début et fin de mesure de performance, etc…

En plus de simplifier le code, ce système le sécurise également car il est vital que le code de fermeture soit appelé (Commit/Rollback, stopWatch.Stop, etc).

Par contre, on peut regretter la syntaxe toujours un peu spéciale des méthodes anonymes ou des expressions lambdas qui apportent un peu de complexité. Pour rappel, un objet est spécialement créé pour porter le contexte d’exécution d’une méthode anonyme, bref on aurait préféré l’utilisation d’un bloc de code classique et c’est tout le propos de ce billet !

Commençons par faire quelques rappels sur le mot clé “using”.

“Using” est très apprécié des développeurs C#, justement pour sa simplicité d’utilisation. Ce mot clé est intimement rattaché à l’interface IDisposable. C’est un des très rares cas où le langage est lié à un élément spécifique du framework.

class Program
{
    static void Main(string[] args)
    {
        using (var t = new Test())
        {
            Console.ReadLine();
        }
        Console.ReadLine();
    }
}
class Test : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("Dispose!");
    }
}

Dans l’exemple ci-dessus, l’instruction “using” assure l’appel de la méthode Dispose après l’exécution de l’instruction (ou du bloc d’instruction) suivant.

Si l’on désassemble l’IL compilé, on voit que le compilateur génère un bloc try…finally pour sécuriser l’appel du Dispose

image

On notera également que IDisposable, même si son nom pourrait le faire croire, n’est lié à aucun mécanisme de libération de mémoire. On l’utilise en général pour assurer une libération de ressource logique. Nous avons donc tout le loisir de l’utiliser pour tout autre besoin.

On peut donc facilement développer quelques classes utilisant IDisposable afin de simplifier et sécuriser l’utilisation d’un simple verrou boolean (true au démarrage, puis false en sorte) ou encore d’une mesure de temps d’exécution comme le montre les exemples ci-dessous:

public class SafeBooleanLock : IDisposable
{
    public bool Lock { get; private set; }
    public SafeBooleanLock()
    {
        Lock = true;
    }
    public void Dispose()
    {
        Lock = false;
    }
}
public class LogExecutionTime : IDisposable
{
    private Stopwatch sw;
    public LogExecutionTime()
    {
        sw = Stopwatch.StartNew();
    }
    public void Dispose()
    {
        sw.Stop();
        Debug.WriteLine(sw.ElapsedMilliseconds);
    }
}

Tout le gain est bien évidemment mesuré côté appelant, le code est factorisé, sécurisé et ce avec un simple bloc de code (sans lambda).

using (new LogExecutionTime())
{
    //Some code...
    Console.ReadLine();
}

Très bonnes vacances et très bonne lecture à tous !

Mitsu

Publicités
Catégories :CSharp Étiquettes : ,