2010-09-29 17 views
6

Sto cercando di scrivere un metodo di estensione generico che cerchiamo di fare a me:scorciatoia per "null se oggetto è nullo, o object.member se l'oggetto non è nullo"

this.startDate = startDateXAttribute.NullOrPropertyOf<DateTime>(() => 
{ 
    return DateTime.Parse(startDateXAttribute.Value); 
}); 

NullOrPropertyOf() sarebbe tornato null se è utilizzato su un oggetto null (ad esempio se startDateXAttribute è null) o restituisce il risultato di un Func se non è nullo.

Come si presenta questo metodo di estensione?

+0

E questo: http://stackoverflow.com/questions/336775/pipe-forwards-in-c/337846#337846 –

+0

... e questo: http://stackoverflow.com/questions/854591/how-to-check-for-null-in-a-deep-lambda-expression/854619 # 854619 –

+3

Nota per i progettisti di linguaggio C#: aggiungere qualcosa come un operatore di dereferenziazione null-safe alla lingua è probabile che sia un caratteristica popolare. :-) –

risposta

24

Non c'è nessuna forma breve per questo; implementarne una è una caratteristica richiesta con frequenza. La sintassi potrebbe essere qualcosa di simile:

x = foo.?bar.?baz; 

Cioè, x è nullo se foo o foo.bar sono nulli, e il risultato di foo.bar.baz se nessuno di loro sono nulli.

L'abbiamo preso in considerazione per il C# 4, ma non è stato posizionato vicino alla parte superiore dell'elenco di priorità. Lo terremo a mente per ipotetiche versioni future della lingua.

UPDATE: C# 6 avrà questa caratteristica. Vedere http://roslyn.codeplex.com/discussions/540883 per una discussione sulle considerazioni di progettazione.

+3

ipotetico? Spero che MS non stia per rilasciare C# così presto;) –

+15

@vc: ti ricordo che le riflessioni di Eric su caratteristiche ipotetiche di prodotti futuri non annunciati che non esistono oggi e che potrebbero non esistere sono * solo per scopi di intrattenimento * e non costituisce una promessa di consegnare qualsiasi prodotto con qualsiasi funzionalità in qualsiasi momento. –

+4

sei la mia definizione per prudente –

1

Il XAttribute Class fornisce un explicit conversion operator per questo:

XAttribute startDateXAttribute = // ... 

DateTime? result = (DateTime?)startDateXAttribute; 

Per il caso generale, l'opzione migliore è probabilmente questo:

DateTime? result = (obj != null) ? (DateTime?)obj.DateTimeValue : null; 
0

È questo quello che stai cercando? Penso che si guasta se si passa un tipo di valore non annullabile, ma dovrebbe funzionare quando si utilizzano tipi nullable. Per favore fatemi sapere se c'è qualcosa che ho trascurato.

public static class Extension 
{ 
    public static T NullOrPropertyOf<T>(this XAttribute attribute, Func<string, T> converter) 
    { 
     if (attribute == null) 
     { 
      return default(T); 
     } 
     return converter.Invoke(attribute.Value); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Func<string, DateTime?> convertDT = (string str) => 
     { 
      DateTime datetime; 
      if (DateTime.TryParse(str, out datetime)) 
      { 
       return datetime; 
      } 
      return null; 
     }; 
     Func<string, string> convertStr = (string str) => 
     { 
      return str; 
     }; 
     XAttribute x = null; 
     Console.WriteLine(x.NullOrPropertyOf<string>(convertStr)); 
     Console.WriteLine(x.NullOrPropertyOf<DateTime?>(convertDT)); 
     XName t = "testing"; 
     x = new XAttribute(t, "test"); 
     Console.WriteLine(x.NullOrPropertyOf<string>(convertStr)); 
     x = new XAttribute(t, DateTime.Now); 
     Console.WriteLine(x.NullOrPropertyOf<DateTime?>(convertDT)); 
    } 
} 
+0

Non è necessario specificare il tipo di parametro lambda dopo aver annotato il tipo su lhs. – nawfal

Problemi correlati