2009-03-10 4 views
8

Esiste un modo migliore/più breve per gestire (molti) riferimenti null, ad esempio quando si utilizza LinqToXML.Gestione di riferimenti null quando si utilizza ad esempio Linq-To-Xml

Ho scritto questa estensione per XElement che la gestisce abbastanza bene, ma forse c'è un altro modo?

E il nome della funzione? "E" non è realmente descrittivo.

public static class XmlExtentions 
{ 
    public static T And<T>(this T obj, Func<T, T> action) where T : XElement 
    { 
     return obj == null ? obj : action(obj); 
    } 
} 

internal class Program 
{ 
    private static void Main() 
    { 
     //create example xml element 
     var x = 
      XElement.Parse("<root><find><name>my-name</name></find></root>"); 

     //old way 
     var test1 = x.Element("find"); 
     if (test1 != null) test1 = test1.Element("name"); 
     Console.WriteLine(test1); 

     //using the extentions method 
     var test2 = x.Element("find").And(findme => findme.Element("name")); 
     Console.WriteLine(test2); 

     Console.ReadLine(); 
    } 
} 

PS: so che potrei usare XPath per questo esempio, ma non è sempre il caso in casi più complessi.

risposta

5

L'approccio generale è ragionevole, anche se non sono sicuro dello Func<T,T> che sembra un po 'restrittivo. Se si sta limitando a restituire la stessa cosa, mi chiedo se solo accettando il nome (string) come il secondo argomento non sarebbe più facile?

Re naming - forse prendere in prestito da LINQ? Questo è essentaially un Select - come circa SelectOrDefault:

public static TResult SelectOrDefault<TSource, TResult>(
    this TSource obj, Func<TSource, TResult> selector) where TSource : class 
{ 
    return SelectOrDefault<TSource, TResult>(
     obj, selector, default(TResult)); 
} 

public static TResult SelectOrDefault<TSource, TResult>(
    this TSource obj, Func<TSource, TResult> selector, 
    TResult @default) where TSource : class 
{ 
    return obj == null ? @default : selector(obj); 
} 

(edit) magari con l'ulteriore XElement specifica:

public static XElement SelectOrDefault(
    this XElement element, XName name) 
{ 
    return element == null ? null : element.Element(name); 
} 
+0

Mi piace il primo esempio, anche se ho potuto solo modificare il mio codice per "dove T : class "e hanno quasi lo stesso risultato. Ma la possibilità di restituire altri tipi è un bel extra! –