Expression C # if-null-then-null

Juste pour la curiosité / la commodité: C # fournit deux fonctions d’expression conditionnelles géniales que je connais:

ssortingng sortingmmed = (input == null) ? null : input.Trim(); 

et

 ssortingng sortingmmed = (input ?? "").Trim(); 

Une autre expression me manque pour une situation que je rencontre très souvent:

Si la référence d’entrée est null, la sortie doit être nulle. Sinon, la sortie devrait être le résultat de l’access à une méthode ou à une propriété de l’object d’entrée.

J’ai fait exactement cela dans mon premier exemple, mais (input == null) ? null : input.Trim() (input == null) ? null : input.Trim() est assez verbeux et illisible.

Existe-t-il une autre expression conditionnelle pour ce cas, ou puis-je utiliser le ?? opérateur avec élégance?

Quelque chose comme l’opérateur de déréférencement null-safe de Groovy?

 ssortingng zipCode = customer?.Address?.ZipCode; 

Je pense que l’équipe C # s’est penchée là-dessus et a constaté que la conception n’était pas aussi simple que l’on pouvait s’y attendre, bien que je n’aie pas entendu parler des problèmes.

Je ne crois pas qu’il y ait une telle chose dans la langue en ce moment, j’ai bien peur … et je n’ai entendu parler d’aucun plan pour cela, même si cela ne veut pas dire que cela n’arrivera pas à un moment donné.

EDIT: Il va maintenant faire partie de C # 6, en tant qu’opérateur “null-conditionnel”.

Vous pouvez choisir entre une classe Nullify personnalisée ou une méthode d’extension NullSafe , comme décrit ici: http://qualityofdata.com/2011/01/27/nullsafe-dereference-operator-in-c/

L’utilisation sera la suivante:

 //Groovy: bossName = Employee?.Supervisor?.Manager?.Boss?.Name //C# Option 1: bossName = Nullify.Get(Employee, e => e.Supervisor, s => s.Manager, m => m.Boss, b => b.Name); //C# Option 2: bossName = Employee.NullSafe( e => e.Supervisor ).NullSafe( s => s.Boss ) .NullSafe( b => b.Name ); 

Actuellement, nous ne pouvons écrire une méthode d’extension que si vous ne voulez pas vous répéter, j’ai bien peur.

 public static ssortingng NullableTrim(this ssortingng s) { return s == null ? null : s.Trim(); } 

Pour contourner ce problème, vous pouvez utiliser ce qui est basé sur Maybe monad .

 public static Tout IfNotNull(this Tin instance, Func Output) { if (instance == null) return default(Tout); else return Output(instance); } 

Utilisez-le de cette façon:

 int result = objectInstance.IfNotNull(r => 5); var result = objectInstance.IfNotNull(r => r.DoSomething()); 

Il n’ya rien d’intégré, mais vous pouvez l’emballer dans une méthode d’extension si vous le vouliez (bien que je ne le ferais probablement pas).

Pour cet exemple spécifique:

 ssortingng sortingmmed = input.NullSafeTrim(); // ... public static class SsortingngExtensions { public static ssortingng NullSafeTrim(this ssortingng source) { if (source == null) return source; // or return an empty ssortingng if you prefer return source.Trim(); } } 

Ou une version plus générale:

 ssortingng sortingmmed = input.IfNotNull(s => s.Trim()); // ... public static class YourExtensions { public static TResult IfNotNull( this TSource source, Func func) { if (func == null) throw new ArgumentNullException("func"); if (source == null) return source; return func(source); } } 

J’ai eu le même problème, j’ai écrit quelques petites méthodes d’extension:

 public static TResult WhenNotNull( this T subject, Func expression) where T : class { if (subject == null) return default(TResult); return expression(subject); } public static TResult WhenNotNull( this T subject, Func expression, TResult defaultValue) where T : class { if (subject == null) return defaultValue; return expression(subject); } public static void WhenNotNull(this T subject, Action expression) where T : class { if (subject != null) { expression(subject); } } 

Vous l’utilisez comme ça;

 ssortingng str = null; return str.WhenNotNull(x => x.Length); 

ou

 IEnumerable list; return list.FirstOrDefault().WhenNotNull(x => x.id, -1); 

ou

 object obj; IOptionalStuff optional = obj as IOptionalStuff; optional.WhenNotNull(x => x.Do()); 

Il existe également des surcharges pour les types nullables.