web-dev-qa-db-fra.com

Un type de référence non nullable en C # 8 peut-il être nul en runtime?

Il me semble qu'il n'y a vraiment aucune garantie qu'une variable non nullable n'aura jamais null. Imaginez que j'ai une classe qui a une propriété qui n'est pas nullable:

public class Foo
{
    public Foo(string test)
    {
        Test = test;
    }
    public string Test {get;set;}
}

Maintenant, cela pourrait sembler être désormais nul. Mais si nous référençons cette classe avec une autre bibliothèque qui n'utilise pas de contexte nullable, rien ne l'empêche d'envoyer null dedans.

Est-ce correct ou il y a peut-être des vérifications d'exécution qui assurent cela?

10
Ilya Chernomordik

C'est ce que MS dit à propos de ( https://docs.Microsoft.com/en-us/dotnet/csharp/tutorials/upgrade-to-nullable-references#interfaces-with-external-code ) :

Le compilateur ne peut pas valider tous les appels à vos API publiques, même si votre code est compilé avec des contextes d'annotation nullables activés. De plus, vos bibliothèques peuvent être consommées par des projets qui n'ont pas encore opté pour l'utilisation de types de référence nullables. Validez les entrées des API publiques même si vous les avez déclarées comme des types non nullables.

8
Dmitri Tsoy

Même dans votre propre code, si vous choisissez de le faire, vous pouvez passer null, à l'aide de l'opérateur nul. null! est considéré comme non nul en ce qui concerne l'analyse de nullité du compilateur.

2

Vous avez raison, un autre code qui n'utilise pas la nouvelle fonctionnalité pourrait affecter null à cette propriété, il n'y a pas de vérification au moment de l'exécution, il s'agit simplement d'indicateurs de conformité.

Vous pouvez toujours le faire vous-même si vous souhaitez une vérification de l'exécution:

public string Test { get; set{ if (value == null) throw new ArgumentNullException() } }

Notez que vous pouvez garantir de ne pas être null dans la plupart de votre code, il vous suffit d'ajouter des gardes à votre API publique de niveau supérieur et de vous assurer que les classes sont correctement scellées, etc.

Bien sûr, les gens peuvent toujours utiliser la réflexion pour f *** votre code, mais alors c'est sur eux

2
Milney

quelqu'un peut toujours faire

var myFoo = new Foo(null);

Peut-être que vous pouvez utiliser la conception pilotée par domaine

public class Foo
{
    public Foo(string test)
    {
         if (string.IsNullOrWhiteSpace(test))
             throw new ArgumentNullException(nameof(test));

         Test = test;
    }
    public string Test {get;private set;}
}
2
huMpty duMpty

Pour gérer les vérifications nulles et rendre votre code lisible, je suggère le modèle Null Object Design.

Plus de lecture ici:

https://www.c-sharpcorner.com/article/null-object-design-pattern/

Fondamentalement, cela implique de créer un nouvel objet qui est dérivé de la même interface et a une instance nulle.

Exemple:

public class NullExample : IExample  
{  
    private static NullExample _instance;  
    private NullExample()  
    { }  

    public static NullExample Instance  
    {  
        get {  
            if (_instance == null)  
                return new NullExample();  
            return _instance;  
        }  
    }  

    //do nothing methods  
    public void MethodImplementedByInterface1()  
    { }  

    public void MethodImplementedByInterface1()  
    { }  
}  

Les valeurs nulles ne peuvent pas être évitées, mais elles peuvent être vérifiées proprement.

0
Gauravsa