DéveloppeurWeb.Com
    DéveloppeurWeb.Com
    • Agile Zone
    • AI Zone
    • Cloud Zone
    • Database Zone
    • DevOps Zone
    • Integration Zone
    • Web Dev Zone
    DéveloppeurWeb.Com
    Home»Uncategorized»Aidez le compilateur et le compilateur vous aidera
    Uncategorized

    Aidez le compilateur et le compilateur vous aidera

    janvier 27, 2023
    Aidez le compilateur et le compilateur vous aidera
    Share
    Facebook Twitter Pinterest Reddit WhatsApp Email

    Les types de référence Nullable sont apparus en C # il y a trois ans. A cette époque, ils ont trouvé leur public. Mais même ceux qui travaillent avec cette «bête» peuvent ne pas connaître toutes ses capacités. Voyons comment travailler avec ces types plus efficacement.

    Introduction

    Les types de référence Nullable sont conçus pour aider à créer une architecture d’application meilleure et plus sûre. Au stade de l’écriture du code, il faut comprendre si telle ou telle variable de référence peut être null ou non, si la méthode peut retourner nulletc.

    Il est sûr de dire que chaque développeur a rencontré NRE (NullReferenceException). Étant donné que cette exception peut être générée au stade du développement, c’est un bon scénario car vous pouvez résoudre le problème immédiatement. C’est bien pire lorsque l’utilisateur trouve le problème lorsqu’il travaille avec le produit. Les types de référence Nullable aident à protéger contre NRE.

    Dans cet article, je parlerai d’un certain nombre de fonctionnalités non évidentes liées aux types de référence nullables. Mais cela vaut la peine de commencer par une brève description de ces types.

    Référence Nullable

    En termes de logique d’exécution de programme, un type de référence nullable n’est pas différent d’un type de référence. La différence entre eux réside uniquement dans l’annotation spécifique du premier. L’annotation permet au compilateur de déterminer si une variable ou une expression particulière peut être null. Pour utiliser des types de référence nullables, vous devez vous assurer que le contexte nullable est activé pour le projet ou le fichier (je décrirai plus tard comment procéder).

    Pour déclarer une variable de référence nullable, ajoutez ‘?’ à la fin du nom du type.

    Exemple:

    Maintenant la variable str peut être null, et le compilateur n’émettra pas d’avertissement pour ce code. Si vous n’ajoutez pas ‘?’ lors de la déclaration d’une variable et de son affectation avec nullun avertissement sera émis.

    Il est possible de supprimer les avertissements du compilateur concernant une éventuelle écriture null à une variable de référence qui n’est pas marquée comme nullable.

    Exemple:

    object? GetPotentialNull(bool flag)
    {
      return flag ? null : new object();
    }
    
    void Foo()
    {
      object obj = GetPotentialNull(false);
    }

    Les obj la variable ne sera jamais affectée avec null, mais le compilateur ne le comprend pas toujours. Vous pouvez supprimer l’avertissement comme suit :

    object obj = GetPotentialNull(false)!;

    En utilisant le ‘!’ opérateur, nous « indiquons » au compilateur que la méthode ne retournera certainement pas null. Par conséquent, il n’y aura aucun avertissement pour ce fragment de code.

    La fonctionnalité disponible lorsque vous travaillez avec des types de référence nullables ne se limite pas à déclarer des variables de ce type (à l’aide de ‘?’) et à supprimer les avertissements avec ‘!.’ Ci-dessous, j’examinerai les fonctionnalités les plus intéressantes lorsque vous travaillez avec des types de référence nullables.

    Travailler avec un contexte Nullable

    Il existe un certain nombre de mécanismes pour un travail plus flexible avec des types de référence nullables. Regardons certains d’entre eux.

    Travailler avec des attributs

    Les attributs peuvent être utilisés pour indiquer au compilateur l’état nul de divers éléments. Voyons les plus intéressants.

    Note: vérifier Attributs pour l’analyse statique à l’état nul interprétés par le compilateur C# pour trouver la liste complète des attributs.

    Pour faciliter les choses, introduisons le terme d’état nul. L’état nul est une information indiquant si une variable ou une expression peut être null à un moment donné.

    Permettre null

    Regardons comment fonctionne l’attribut. Voici un exemple:

    public string Name
    {
      get => _name;
      set => _name = value ?? "defaultName";
    }
    
    private string _name;

    Si vous écrivez le null valeur à la Name propriété, le compilateur émettra un avertissement : « Impossible de convertir un littéral nul en un type de référence non nullable ». Mais vous pouvez voir à partir de l’implémentation de la propriété qu’elle peut être null. Dans ce cas, le defaultName la chaîne est affectée au _name domaine.

    Si vous ajoutez ‘?’ au type de propriété, le compilateur supposera que :

    • L’accesseur d’ensemble peut accepter null (c’est correct).
    • L’accesseur get peut retourner null (c’est une erreur).

    Pour une mise en œuvre correcte, il convient d’ajouter le AllowNull attribut à la propriété :

    [AllowNull]
    public string Name

    Après cela, le compilateur supposera que Name peut être affecté avec null, bien que le type de la propriété ne soit pas marqué comme nullable. Si vous affectez la valeur de cette propriété à une variable qui ne doit jamais être nullalors il n’y aura pas d’avertissements.

    NonNullQuand

    Supposons que nous ayons une méthode qui vérifie une variable pour null. En fonction du résultat de cette vérification, la méthode renvoie une valeur de bool taper. Cette méthode nous informe sur l’état nul de la variable.

    Voici un exemple de code synthétique :

    bool CheckNotNull(object? obj)
    {
      return obj != null;
    }

    Cette méthode vérifie la obj paramètre pour null et renvoie une valeur de bool type en fonction du résultat de la vérification.

    Utilisons le résultat de cette méthode dans la condition :

    public void Foo(object? obj1)
    {
      object obj2 = new object();
    
      if (CheckNotNull(obj1))
        obj2 = obj1;
    }

    Le compilateur émettra un avertissement au code ci-dessus : « Conversion d’un littéral nul ou éventuellement d’une valeur nulle en type non nullable ». Mais un tel scénario est impossible, puisque la condition garantit que obj1 n’est pas null dans la branche d’alors. Le problème est que le compilateur ne comprend pas cela, nous devons donc l’aider.

    Changeons la signature du CheckNotNull méthode en ajoutant le NotNullWhen attribut:

    bool CheckNotNull([NotNullWhen(true)]object? obj)

    Cet attribut prend une valeur de bool type comme premier argument. Avec NotNullWhen, nous lions l’état nul de l’argument avec la valeur de retour de la méthode. Dans ce cas, nous « disons » au compilateur que si la méthode renvoie truel’argument a une valeur autre que null.

    Il y a une particularité associée à cet attribut.

    Voici quelques exemples:

    En utilisant le en dehors modificateur:

    bool GetValidOrDefaultName([NotNullWhen(true)] out string? validOrDefaultName, 
                               string name)
    {
      if (name == null)
      {
        validOrDefaultName = name;
        return true;
      }
      else
      {
        validOrDefaultName = "defaultName";
        return false;
      }
    }

    Ici, le compilateur émettra un avertissement : « Paramètre validOrDefaultName doit avoir une valeur non nulle lors de la sortie avec true.” C’est tout à fait raisonnable, puisque ‘==’ est utilisé dans la condition au lieu de l’opérateur ‘!=’. Dans cette implémentation, la méthode renvoie true lorsque validOrDefaultName est null.

    En utilisant le réf modificateur:

    bool SetDefaultIfNotValid([NotNullWhen(true)] ref string? name)
    {
      if (name == null)
        return true;
    
      name = "defaultName";
      return false;
    }

    Nous recevrons également un avertissement pour ce fragment de code : « Paramètre name doit avoir une valeur non nulle lors de la sortie avec true.” Comme dans l’exemple précédent, l’avertissement est raisonnable. ‘==’ est utilisé à la place de l’opérateur ‘!=’.

    Sans utiliser de modificateur :

    bool CheckingForNull([NotNullWhen(true)] string? name)
    {
      if (name == null)
        return true;
    
      Console.WriteLine("name is null");
      return false;
    }

    La situation ici est similaire aux cas précédents. Si name équivaut à nullla méthode renvoie true. Suivant la logique des exemples précédents, un avertissement doit également être émis ici : « Paramètre name doit avoir une valeur non nulle lors de la sortie avec true.” Cependant, il n’y a pas d’avertissement. Il est difficile de dire ce qui a causé cela, mais cela semble étrange.

    NonNullSiNonNull

    Cet attribut permet d’établir une relation entre l’argument et la valeur de retour de la méthode. Si l’argument n’est pas nullla valeur de retour n’est pas non plus nullet vice versa.

    Exemple:

    public string? GetString(object? obj)
    {
      return obj == null ? null : string.Empty;
    }

    Les GetString la méthode renvoie null ou une chaîne vide, selon l’état nul de l’argument.

    Utilisation de cette méthode :

    public void Foo(object? obj)
    {
      string str = string.Empty;
    
      if(obj != null)
        str = GetString(obj);
    }

    Avertissement du compilateur pour ce code : « Conversion d’un littéral null ou éventuellement d’une valeur null en un type non nullable. » Dans ce cas, le compilateur ment. L’affectation est effectuée dans le corps de ifdont la condition garantit que GetString ne reviendra pas null. Pour aider le compilateur, ajoutons le NotNullIfNotNull attribut pour la valeur de retour de la méthode :

    [return: NotNullIfNotNull("obj")]
    public string? GetString(object? obj)

    Note: À partir de C#11, vous pouvez obtenir le nom du paramètre à l’aide de la nameof expression. Dans ce cas, ce serait nameof(obj).

    Les NotNullIfNotNull L’attribut prend la valeur du type de chaîne comme premier argument – le nom du paramètre, sur la base duquel l’état nul de la valeur de retour est défini. Maintenant, le compilateur a des informations sur la relation entre obj et la valeur de retour de la méthode : si obj n’est pas nullla valeur de retour de la méthode ne sera pas null, et vice versa.

    MemberNotNull

    Commençons par un exemple :

    class Person
    {
      private string _name;
    
      public Person()
      {
        SetDefaultName();
      }
    
      private void SetDefaultName()
      {
        _name = "Bob";
      }
    }

    Le compilateur émettra un avertissement sur ce fragment de code : « Champ non nul _name doit contenir une valeur non nulle lors de la sortie du constructeur. Envisagez de déclarer le champ comme nullable. Cependant, le SetDefaultName La méthode est appelée dans le corps du constructeur, qui initialise le seul champ de la classe. Cela signifie que le message du compilateur est faux. Les MemberNotNull L’attribut vous permet de résoudre le problème :

    [MemberNotNull(nameof(_name))]
    private void SetDefaultName()

    Cet attribut prend un argument de la string[] tapez avec le ‘paramètres’ mot-clé. Les chaînes doivent correspondre aux noms des membres initialisés dans la méthode.

    Ainsi, nous indiquons que la valeur de la _name le champ ne sera pas null après l’appel de cette méthode. Maintenant le…

    Share. Facebook Twitter Pinterest LinkedIn WhatsApp Reddit Email
    Add A Comment

    Leave A Reply Cancel Reply

    Catégories

    • Politique de cookies
    • Politique de confidentialité
    • CONTACT
    • Politique du DMCA
    • CONDITIONS D’UTILISATION
    • Avertissement
    © 2023 DéveloppeurWeb.Com.

    Type above and press Enter to search. Press Esc to cancel.