Is there a way to Imitate C# 6 Null-Conditional op

2020-07-13 09:10发布

问题:

I have a situation where I need to assign some objects' properties inside an object initializer. Some of these objects can be null and I need to access their properties, the problem is that they are too many, and using a if/else thing is not good.

Example

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

The joined.VisitePdvProduit can be null, and the problem is that there are like dozens of such assignments (I just took one to shorten the code)

The C# 6 Null-Conditional operator is the perfect solution for this situation, the problem is that I'm on C# 5 in this project, is there a way to imitate that ?

回答1:

Well, you can use an extension method that receives an accessor delegate and only executes it if the item isn't null:

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);
    }
}

You can use it for example like this:

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

You can easily create versions of this method for operations that don't return a value (i.e. bar.ConditionalAccess(_ => _.Foo())) or return value types.



回答2:

Like this. Ugly, but what had to be done.

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


回答3:

If you are talking about the semi-very surprised operator ?., then no. There's no way to mimic the syntax.

What you can do, though, is to create an extension method (or a helper method, static one, preferably) or an instance method working with the properties.

Or, as someone suggested, just use the conditional statement (inline or explicit). But that's not what you're looking for, of course.

One more method (and it's not at all recommendable) is to surround the assignment with a try-catch. But that's really baaad solution and I only mention it for completeness' sake.