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

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

在视图中的表中显示客户的邮寄地址时,请考虑使用以下代码:

1
<%: Customer.MailingAddress == null ?"" : Customer.MailingAddress.City %>

我发现自己使用了相当数量的这些三元条件语句,我想知道是否有一种方法可以引用在条件中被评估的对象,以便在表达式中使用它。可能是这样的:

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

这样的东西存在吗?我知道我可以创建一个变量来保存这个值,但是最好将所有内容都保存在视图页面中一个紧凑的小语句中。

谢谢!


为什么不在包含该条件的客户对象上创建一个属性,并直接调用它呢?即

1
Customer.FormattedMailingAddress

我会写代码,但我在我的手机上,你只需要把同样的条件放在get{}里。


不,没有一种方法可以在不创建变量或复制自己的情况下精确地执行您的请求,但是您可以这样做:

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

这假定一个新的mailingaddress默认为其city属性/字段为空。

如果创建新的mailingaddress将city字段/属性初始化为空字符串,则可以删除最后一个空合并。

但事实上,它并不短,而且更具黑客风格(在我看来),而且几乎可以肯定的是,它的性能更低。


可以使用??运算符与空进行比较。

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

上述内容可改写如下:

1
Customer.MailingAddress ??"";

在您的案例中,我通常创建扩展方法:

1
2
3
4
5
6
7
8
9
10
public static TValue GetSafe<T, TValue>(this T obj, Func<T, TValue> propertyExtractor)
where T : class
{
    if (obj != null)
    {
        return propertyExtractor(obj);
    }

    return null;
}

使用方法如下:

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


您可以创建一个扩展方法来获取值或返回一个空字符串:

1
2
3
4
5
6
7
    public static string GetValue<T>(this T source, Func<T, string> getter)
    {
        if (source != null)
            return getter(source);

        return"";
    }

然后称之为:

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

这对任何对象都有效。


我同意@dave,为您的客户类创建一个扩展。

像这样:

1
2
3
4
5
6
7
public static class CustomerExtension
{
    public static string DisplayCity(this Customer customer)
    {
        return customer.MailingAddress == null ? String.Empty : customer.MailingAddress.City
    }
}

然后您可以这样调用您的方法:

1
myCustomer.DisplayCity();

(注意:无法将扩展创建为属性,因此这必须是一个方法。请参见C是否具有扩展属性?更多详细信息)