使用三元运算构建字符串

Building a string using ternary operations

我正在尝试使用三元运算构建一个字符串并将其传递给 Excel 文件的单元格。这是我的代码:

            ws.Rows[index].Cells[24].Value = i.IliskiliCokluIsler.Count == 0 ?

                i.IliskiliMahalle.MahalleAdi != null ? i.IliskiliMahalle.MahalleAdi + " Mahallesi" : "" + 
                i.IliskiliYerGorme.BulvarCadde != null ? i.IliskiliYerGorme.BulvarCadde + " Cadde" : "" +
                i.IliskiliYerGorme.Sokak != null ? i.IliskiliYerGorme.Sokak + " Sokak" : "" + 
                i.IliskiliYerGorme.BinaNo != null ? "Bina no : " + i.IliskiliYerGorme.BinaNo : "" + 
                i.IliskiliYerGorme.KatNo != null ? i.IliskiliYerGorme.KatNo + " Kat" : "" +
                i.IliskiliIlce.IlceAdi + i.IliskiliSehir.SehirAdi : "";

我知道 i.IliskiliIlce.IlceAdii.IliskiliSehir.SehirAdi 以及 i.IliskiliYerGorme.KatNo 不为空。当我 运行 代码时,我只得到

X Mahallesi

即我无法获取其他实体,无论它们是否为空。我哪里做错了?使用这样的三元运算生成字符串的想法是错误的吗?我怎样才能以正确的方式做到这一点?谢谢。

这几乎可以肯定是由于运算符的优先级; + 的优先级高于 ?:,也就是说,如果我们只取前几行:

i.IliskiliMahalle.MahalleAdi != null ? i.IliskiliMahalle.MahalleAdi + " Mahallesi" : "" + 
i.IliskiliYerGorme.BulvarCadde != null ? i.IliskiliYerGorme.BulvarCadde + " Cadde" : ""

它将评估为:

i.IliskiliMahalle.MahalleAdi != null ? i.IliskiliMahalle.MahalleAdi + " Mahallesi" :
    ("" + i.IliskiliYerGorme.BulvarCadde != null ? 
        i.IliskiliYerGorme.BulvarCadde + " Cadde" : "")

这不是你想要的。您可以通过用括号括起每一行来解决此问题:

ws.Rows[index].Cells[24].Value = i.IliskiliCokluIsler.Count == 0 ?
(i.IliskiliMahalle.MahalleAdi != null ? i.IliskiliMahalle.MahalleAdi + " Mahallesi" : "") + 
(i.IliskiliYerGorme.BulvarCadde != null ? i.IliskiliYerGorme.BulvarCadde + " Cadde" : "") +
(i.IliskiliYerGorme.Sokak != null ? i.IliskiliYerGorme.Sokak + " Sokak" : "") + 
(i.IliskiliYerGorme.BinaNo != null ? "Bina no : " + i.IliskiliYerGorme.BinaNo : "") + 
(i.IliskiliYerGorme.KatNo != null ? i.IliskiliYerGorme.KatNo + " Kat" : "") +
(i.IliskiliIlce.IlceAdi + i.IliskiliSehir.SehirAdi : "");

但是,如果这是一段经常 运行 的代码,我会考虑改用 StringBuilder

为此我建议提取方法

  private static string NvlSuffix(string value, string suffix) {
    return (null == value) ? "" : value + " " + suffix;
  }

  private static string NvlPrefix(string value, string prefix) {
    return (null == value) ? "" : prefix + " " + value;
  }

...

  ws.Rows[index].Cells[24].Value = i.IliskiliCokluIsler.Count == 0 
    ? string.Concat(
        NvlSuffix(i.IliskiliMahalle.MahalleAdi, "Mahallesi"),
        NvlSuffix(i.IliskiliYerGorme.Sokak, "Sokak"),
        NvlPrefix(i.IliskiliYerGorme.BinaNo, "Bina no"), 
        NvlSuffix(i.IliskiliYerGorme.KatNo, "Kat"),
        i.IliskiliIlce.IlceAdi, 
        i.IliskiliSehir.SehirAdi)
    : ""; 

仅提取了两种方法,代码就变成了一种可读性更高,因此更易于调试不要重复自己

很可能连编译器都被那些长长的“?:”弄糊涂了。我会用表达式写一个简单的扩展方法。

    public static string GeName<T>(this T source, Expression<Func<T, string>> selector, string addOn) where T : class 
    {
        if (source == null) return string.Empty;

        var func = selector.Compile();
        var value = func(source);

        return value == null ? string.Empty : string.Format("{0} {1}", value, addOn);
    }

它检查 属性 是否也为空。这样代码会更干净,更易读:

var value = i.IliskiliCokluIsler.Count == 0 
    ? string.Empty
    : i.IliskiliMahalle.GetName(m => m.MahalleAdi, " Mahallesi") 
        + ....
        + ....;

ws.Rows[index].Cells[24].Value = value;