简体   繁体   English

ASP.NET MVC / C#:我可以避免在单行C#条件语句中重复自己吗?

[英]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: 在视图中的表中显示Customer的邮件地址时,请考虑以下代码:

<%: Customer.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! 谢谢!

You can use ?? 你可以用?? operator for comparisons with null. 运算符用于与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

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. 这假定默认情况下新的MailingAddress将使其city属性/字段为null。

The last null coalescence can be removed if creating a new MailingAddress initializes the city field / property to empty string. 如果创建新的MailingAddress将city字段/属性初始化为空字符串,则可以删除最后一个空合并。

But this isn't actually shorter, and it's more hackish (in my opinion), and almost certainly less performant. 但这实际上并不短,而且在我看来更为苛刻,而且几乎肯定不那么高效。

Why not create a property on the Customer object which contains that condition and just call it directly? 为什么不在包含该条件的Customer对象上创建属性并直接调用它? ie

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. 我会编写代码但是我在移动设备上,你只需要在get{}相同的条件。

I agree with @Dave, create an extension for your Customer class. 我同意@Dave,为您的Customer类创建一个扩展。

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) (注意:扩展不能作为属性创建,因此这必须是一个方法。有关详细信息,请参阅C#是否具有扩展属性?

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. 这适用于任何对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM