开发者

ASP.NET MVC/C#: Can I avoid repeating myself in a one-line C# conditional statement?

Consider the following code that I'm using when displaying a Customer's mailing address inside a table in a view:

<%: Custom开发者_C百科er.MailingAddress == null ? "" : Customer.MailingAddress.City %>

I find myself using a fair amount of these ternary conditional statements and I am wondering if there is a way to refer back to the object being evaluated in the condition so that I can use it in the expression. Something like this, perhaps:

<%: Customer.MailingAddress == null ? "" : {0}.City %>

Does something like this exist? I know I can create a variable to hold the value but it would be nice to keep everything inside one tight little statement in the view pages.

Thanks!


No, there is not a way to do precisely what you're asking without creating a variable or duplicating yourself, though you can do something like this:

(Customer.MailingAddress ?? new MailingAddress()).City ?? string.Empty

This presumes that a new MailingAddress will have it's city property / field null by default.

The last null coalescence can be removed if creating a new MailingAddress initializes the city field / property to empty string.

But this isn't actually shorter, and it's more hackish (in my opinion), and almost certainly less performant.


You can use ?? operator for comparisons with null.

Customer.MailingAddress == null ? "" : Customer.MailingAddress;

Above can be rewritten as following:

Customer.MailingAddress ?? "";

In your case I usually create extension method:

public static TValue GetSafe<T, TValue>(this T obj, Func<T, TValue> propertyExtractor)
where T : class
{
    if (obj != null)
    {
        return propertyExtractor(obj);
    }

    return null;
}

And usage would be like this:

Customer.GetSafe(c => c.MailingAddress).GetSafe(ma => ma.City) ?? string.Empty


Why not create a property on the Customer object which contains that condition and just call it directly? i.e.

Customer.FormattedMailingAddress

I'd write the code but I'm on my mobile, you'd only need to put the same condition inside the get{} though.


I agree with @Dave, create an extension for your Customer class.

Something like this:

public static class CustomerExtension
{
    public static string DisplayCity(this Customer customer)
    {
        return customer.MailingAddress == null ? String.Empty : customer.MailingAddress.City
    }
}

Then you can call your method like this:

myCustomer.DisplayCity();

(note: extensions can not be created as a property, so this would have to be a method. see Does C# have extension properties? for more details)


You could create an extension method to get the value or return an empty string:

    public static string GetValue<T>(this T source, Func<T, string> getter)
    {
        if (source != null)
            return getter(source);

        return "";
    }

then call it:

<%: Customer.MailingAddress.GetValue(x=>x.City) %>

This would work for any object.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜