开发者

Is there a coalesce operator for properties of properties in c#?

So there is the coalescing operator ?? that allows handy handling of null objects (IE. MyDisplayString = MyString ?? "n/a";)

but is there a nice fancy operator for handling a similar situation on properties of objects? For instance lets say that the property you are interested in is a property of a property like: MyDataObject.MySubModel.MyProperty

If MyProperty is null you want coalesce to "n/a". You can u开发者_如何学Cse ?? here, but what if MyDataObject is null or MyDataObject.MySubModel?

This also comes up with XML when trying to get optional attributes and elements of an element. IE: MyString = MyElement.Attribute("MyOptionalAttribute").Value ?? "n/a"; fails if the attribute isn't there.

Is there a nice fancy way of handling this scenario?


Is there a nice fancy way of handling this scenario?

You are not the first one asking for this feature. One way is to write a "With" extension method to fetch property values, since extension methods can handle being called on a null reference. Instead of

thing.Foo.Bar

you would write

thing.With(x => x.Foo).With(x => x.Bar)


In C# 5 and below as stated in other answers you need to build something yourself. Instead of using an Extension method as others have here we use a Helper, that we call NN since we use it a LOT, especially in Razor.

public static TValue N<TParent, TValue>(TParent o, Func<TParent, TValue> accessor, TValue defaultValue)
{
    if (o == null)
        return defaultValue;

    return accessor(o);
}

/// <summary>
/// Guarantees return of null or value, given a prop you want to access, even if the parent in the first argument
/// is null (instead of throwing).
/// 
/// Usage:
/// 
/// NN.N(myObjThatCouldBeNull, o => o.ChildPropIWant)
/// </summary>
/// <returns>The value of the prop. Null if the object is null, or if the child prop is null.</returns>
public static TValue N<TParent, TValue>(TParent o, Func<TParent, TValue> accessor)
    where TValue : class
{
    return NN.N(o, accessor, null);
}

We actually use a few helpers depending on the desired behavior when null is encountered; for example you might be accessing an int property and want 0. Full code in the linked Gist.

In C# 6, you can use the null property coalescence operator:

myObjThatCouldBeNull?.ChildPropIWant

More about it:

https://roslyn.codeplex.com/discussions/540883


The Null Object Pattern

a Null Object is an object with defined neutral ("null") behavior

may help you avoid this problem.

Another option is to use extension methods, then you can say:

if (Contract
    .NullSafe(c => c.Parties)
    .NullSafe(p => p.Client)
    .NullSafe(c => c.Address) != null)
{
    // do something with the adress
    Console.Writeline(Contract.Parties.Client.Adress.Street);
}


As I noted here:

Shortcut for "null if object is null, or object.member if object is not null"

this is a fairly frequently requested feature that did not make the bar for C# 4. We'll consider it for hypothetical future versions of the language, but it is not high on the priority list so I would not hold out much hope if I were you.


There might be a better or more elegant way of handling the issue you're describing, but I've found that typically I have to check for nulls along the way, i.e.:

MyString = MyElement.Attribute("MyOptionalAttribute") != null ? MyElement.Attribute("MyOptionalAttribute").Value : "n/a";


In the case of XElement/XAttribute, you can use the explicit conversion operators:

string myString = (string)myElement.Attribute("MyOptionalAttribute") ?? "n/a";

For the general case, a 'safe dereferencing operator' is a fairly frequently requested feature.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜