Comment puis-je écrire un raccourci du scénario suivant?
get
{
if (_rows == null)
{
_rows = new List<Row>();
}
return _rows;
}
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.
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.
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>();
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.
List<Row> _rows;
public List<Row> Rows => _rows ?? (_rows = new List<Row>());
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é.
Quelques clics plus tard, et la modification est mise en œuvre.
Comme ceci par exemple:
get{ return _rows ?? (_rows = new List<Row>()); }
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.
return _rows ?? (_rows = new List<Row>());
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>();
}
Si vous vouliez vraiment le raccourcir, je supprimerais simplement les supports supplémentaires.
get
{
if (_rows == null)
_rows = new List<Row>();
return _rows;
}