2015-12-01 10 views
5

nachzuahmen Ich habe eine Situation, in der ich Eigenschaften einiger Objekte innerhalb eines Objektinitialisierers zuweisen müssen. Einige dieser Objekte können null sein, und ich muss auf ihre Eigenschaften zugreifen, das Problem ist, dass sie zu viele sind, und die Verwendung einer if/else-Sache ist nicht gut.Gibt es eine Möglichkeit, C# 6 Null-Conditional-Operator in C# 5

Beispiel

visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV() 
{ 
    VisiteId = joined.Visite.VisiteId.ToString(), 
    NomPointDeVente = joined.VisitePdvProduit.PointDeVente.NomPointDeVente,    
}); 

Die joined.VisitePdvProduit null sein kann, und das Problem ist, dass es wie Dutzende solcher Zuweisungen sind (ich habe nur einen, den Code zu verkürzen)

Die C# 6Null-Conditional operator ist die perfekte Lösung für diese Situation, das Problem ist, dass ich auf C# 5 in diesem Projekt bin, gibt es eine Möglichkeit, das zu imitieren?

+1

eine Erweiterungsmethode erstellen – MikeSW

+1

Wie wäre es 'visitJoins.AsEnumerable(). Wo (vj => vj.VisitePdvProduit! = Null) .Select (verbunden => new VisitPDV()' –

+0

@ClayVerValen wie gesagt, ich habe mehrere Zuweisungen So, ich habe es gekürzt, um langen Code hier zu vermeiden, Ihren Vorschlag zu tun wird nicht helfen. – AymenDaoudi

Antwort

6

Nun können Sie eine Erweiterungsmethode verwenden, die einen Accessor Delegat empfängt und führt es nur dann, wenn das Element nicht null ist:

public static TResult ConditionalAccess<TItem, TResult>(this TItem item, Func<TItem, TResult> accessor) where TResult : Class 
{ 
    if (item == null) 
    { 
     return null; 
    } 
    else 
    { 
     return accessor(item); 
    } 
} 

Sie können es zum Beispiel wie folgt verwenden:

NomPointDeVente = joined.VisitePdvProduit.ConditionalAccess(_ => _.PointDeVente.NomPointDeVente); 

Sie können problemlos Versionen dieser Methode für Vorgänge erstellen, die keinen Wert zurückgeben (z. B. bar.ConditionalAccess(_ => _.Foo())) oder Werttypen zurückgeben.

+0

Dies würde nur für die Top-Level-Eigenschaftserweiterung funktionieren. – Amy

+1

@Amy Warum? Sie können die Erweiterung mehrmals verwenden ... – i3arnon

+1

ziemlich ordentlich thx – AymenDaoudi

1

So. Hässlich, aber was musste getan werden.

visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV() 
{ 
    VisiteId = joined.Visite.VisiteId.ToString(), 
    NomPointDeVente = (joined.VisitePdvProduit == null) ? null : joined.VisitePdvProduit.PointDeVente.NomPointDeVente,    
}); 
+1

Verdient keinen Downvote, nicht sicher, warum, wahr, es ist lil bisschen hässlich, wie Sie sagten, aber es macht den Job, und es ist verständlich, upvoted – AymenDaoudi

0

Wenn Sie über den halb sehr überrascht Operator sprechen?., dann nicht. Es gibt keine Möglichkeit, die Syntax nachzuahmen.

Sie können jedoch eine Erweiterungsmethode (oder eine Hilfsmethode, vorzugsweise eine statische Methode) oder eine Instanzmethode erstellen, die mit den Eigenschaften arbeitet.

Oder, wie jemand vorgeschlagen, nur die bedingte Anweisung (Inline oder explizit) verwenden. Aber das ist natürlich nicht das, wonach Sie suchen.

Eine weitere Methode (und es ist durchaus nicht empfehlenswert) ist die Zuordnung mit einem try-catch zu umgeben. Aber das ist wirklich baaad Lösung und ich erwähne es nur der Vollständigkeit halber.

+0

Nein. [Dieser Operator: '?. '] (https://msdn.microsoft.com/en-us/library/dn986595.aspx). –

+1

" sehr überrascht Operator "? Ist das ein Tippfehler? – Amy

+0

Ja @NickWhaley, dass man, Thx für die Präzision – AymenDaoudi