web-dev-qa-db-fra.com

Existe-t-il un moyen abrégé de renvoyer des valeurs qui pourraient être nulles?

Comment puis-je écrire un raccourci du scénario suivant?

get
{
    if (_rows == null)
    {
        _rows = new List<Row>();
    }

    return _rows;
}
61
ErrorAgain

En utilisant opérateur de coalescence nulle (??):

get 
{ 
     _rows = _rows ?? new List<Row>(); 
     return _rows; 
}

OU (moins lisible):

get { return _rows ?? (_rows = new List<Row>()); }

Le ?? est appelé opérateur à coalescence nulle. Il retourne l'opérande de gauche si l'opérande n'est pas nul; sinon, elle renvoie l'opérande de droite.

81
Zein Makki

Il s'agit du modèle d'initialisation paresseux, donc la manière la plus simple serait d'utiliser la classe Lazy <T> .

class Foo
{
    Lazy<List<Row>> _rows;

    public Foo()
    {
        _rows = new Lazy(() => new List<Row>());
    }

    public List<Row> Rows
    {
        get { return _rows.Value; }
    }
}

Cela a l'avantage supplémentaire de ne pas "polluer" le getter avec la logique d'initialisation.

41
Roman Reiner

Je suggère ternaire opérateur

get {
  return _rows == null ? _rows = new List<Row>() : _rows;
}

Ou depuis vide List<Row> n'apporte pas beaucoup de frais généraux pourquoi ne pas se débarrasser des explicites _row champ et implémente juste la propriété en lecture seule (C # 6. syntaxe):

public IList<Row> Rows {get;} = new List<Row>();
20
Dmitry Bychenko

Voici une meilleure idée: Empêcher _rows d'être jamais null.

Faites initialiser la variable par votre constructeur:

public MyClass()
{
    this._rows = new List<Row>();
}

puis votre propriété est juste

get
{
    return this._rows;
}

Assurez-vous que si vous devez "effacer" la variable, vous appelez toujours sa méthode Clear ou affectez une nouvelle liste vide au lieu d'affecter null. Peut-être encodez cette opération dans une méthode si vous avez vraiment besoin de la rendre claire et cohérente dans toute la classe.

C'est beaucoup plus logique. Si votre variable ne doit jamais être null, elle ne doit jamais être null. Il évite également parfaitement le conditionnel et le problème d'avoir un état de modification getter.

18
jpmc26
List<Row> _rows;
public List<Row> Rows => _rows ?? (_rows = new List<Row>());
12
Sinatr

Comme d'autres l'ont dit, vous pouvez utiliser l'opérateur de coalescence nulle dans ce scénario.

get
{
    return _rows ?? (_rows = new List<Row>());
}

Il convient de noter que c'est le type de changement que ReSharper est excellent à suggérer (ils l'appellent correction rapide ).

Dans votre exemple, il placera un petit squiggle sous l'instruction if. Le survoler révèle un suggestion pour la façon dont le code pourrait être modifié/simplifié.

Convert to '??' expression

Quelques clics plus tard, et la modification est mise en œuvre.

enter image description here

10
Richard Everett

Comme ceci par exemple:

get{ return _rows ?? (_rows = new List<Row>()); }
5
eocron

Si vous voulez que votre code se comporte comme votre code actuel, en initialisant paresseusement votre champ de sauvegarde lors de l'accès à la propriété, alors oui, vous pouvez le raccourcir. Vous pouvez renommer votre champ de support, comme déjà répondu, utilisez ?? pour tout mettre dans une seule expression, et lorsque vous avez cette seule expression, utilisez la nouvelle syntaxe de propriété de C # 6 pour éviter d'écrire get et return:

List<Row>_;List<Row> Rows=>_??(_=new List<Row>());

Espérons que, bien avant d'arriver à ce point, vous verrez que vous avez transformé un code facile à comprendre qui fait exactement ce que vous voulez en un horrible gâchis que vous ne voudriez jamais maintenir.

Gardez simplement votre code tel qu'il est. Vous pouvez le raccourcir, comme indiqué, mais cela ne le rend pas meilleur.

Si le problème est qu'il prend plus de temps à écrire, car vous continuez à taper le même code encore et encore, de nombreux IDE fournissent une fonctionnalité pour insérer des modèles, des extraits de code ou tout autre terme qu'ils utilisent. Cela vous permet de définir quelque chose le long des lignes de

{Type} {Field};
public {Type} {Property} {
  get {
    if ({Field} == null) {
      {Field} = new {Type}();
    }
    return {Field};
  }
}

où votre éditeur vous demandera ensuite le {Type}, {Champ}, {Propriété} spécifique, sans avoir à le taper à chaque fois.

3
user743382
return _rows ?? (_rows = new List<Row>());
1
Dmitriy Kovalenko

Vous pouvez le faire de l'une des manières suivantes:

  • Opérateur conditionnel (? :)
  • Opérateur coalescent nul (??)

Avec opérateur conditionnel

get {
  return _rows == null ? new List<Row>() : _rows;
}

Opérateur coalescent nul

get { 
  return _rows ?? new List<Row>(); 
}
0
Abdul Moiz Khan

Si vous vouliez vraiment le raccourcir, je supprimerais simplement les supports supplémentaires.

    get
    {
        if (_rows == null)
            _rows = new List<Row>();

        return _rows;
    }
0
Tyler Nichols