Juste pour la curiosité/commodité: C # fournit deux fonctionnalités d'expression conditionnelle intéressantes que je connais:
string trimmed = (input == null) ? null : input.Trim();
et
string trimmed = (input ?? "").Trim();
Je manque une autre expression de ce genre pour une situation à laquelle je fais face très souvent:
Si la référence d'entrée est nulle, alors la sortie doit être nulle. Sinon, la sortie doit être le résultat de l'accès à une méthode ou une propriété de l'objet d'entrée.
C'est exactement ce que j'ai fait dans mon premier exemple, mais (input == null) ? null : input.Trim()
est assez verbeux et illisible.
Y a-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 sans danger de Groovy?
string zipCode = customer?.Address?.ZipCode;
Je suppose que l'équipe C # a examiné cela et a constaté que ce n'était pas aussi simple à concevoir avec élégance qu'on pourrait s'y attendre ... même si je n'ai pas entendu parler des détails des problèmes.
Je ne crois pas qu'il y ait une telle chose dans la langue en ce moment, je le crains ... et je n'ai pas entendu de plans pour cela, bien que cela ne signifie pas que cela ne se produira pas à un moment donné.
EDIT: Cela va maintenant faire partie de C # 6, en tant que "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 -en-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, je le crains.
public static string NullableTrim(this string s)
{
return s == null ? null : s.Trim();
}
Comme solution de contournement, vous pouvez utiliser ceci qui est basé sur Peut-être monade .
public static Tout IfNotNull<Tin, Tout>(this Tin instance, Func<Tin, Tout> 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'y a rien de intégré, mais vous pouvez tout récapituler dans une méthode d'extension si vous le souhaitez (bien que je ne le dérangerais probablement pas).
Pour cet exemple spécifique:
string trimmed = input.NullSafeTrim();
// ...
public static class StringExtensions
{
public static string NullSafeTrim(this string source)
{
if (source == null)
return source; // or return an empty string if you prefer
return source.Trim();
}
}
Ou une version plus générale:
string trimmed = input.IfNotNull(s => s.Trim());
// ...
public static class YourExtensions
{
public static TResult IfNotNull<TSource, TResult>(
this TSource source, Func<TSource, TResult> 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<T, TResult>(
this T subject,
Func<T, TResult> expression)
where T : class
{
if (subject == null) return default(TResult);
return expression(subject);
}
public static TResult WhenNotNull<T, TResult>(
this T subject, Func<T, TResult> expression,
TResult defaultValue)
where T : class
{
if (subject == null) return defaultValue;
return expression(subject);
}
public static void WhenNotNull<T>(this T subject, Action<T> expression)
where T : class
{
if (subject != null)
{
expression(subject);
}
}
Vous l'utilisez comme ceci;
string str = null;
return str.WhenNotNull(x => x.Length);
ou
IEnumerable<object> 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.