1

I'm trying to build a string using ternary operations and pass it to a cell of an Excel file. Here is my code:

            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 know that i.IliskiliIlce.IlceAdi and i.IliskiliSehir.SehirAdi and i.IliskiliYerGorme.KatNo are not null. When I run the code I only get

X Mahallesi

Namely I can't get other entities whether or not they are null. Where am I doing wrong? Is the idea of generating string using ternary operations like that is wrong? How can I do it in the right way? Thanks.

jason
  • 6,962
  • 36
  • 117
  • 198

3 Answers3

3

This is almost certainly down to operator precedence; + has a higher precedence than ?:, that is, if we take just the first couple of lines:

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

It will be evaluating them as:

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

Which is not what you want. You can fix this by surrounding each of your lines with parentheses:

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 : "");

If this is an often-run bit of code, however, I would consider using a StringBuilder instead.

Hans Kesting
  • 38,117
  • 9
  • 79
  • 111
James Thorpe
  • 31,411
  • 5
  • 72
  • 93
  • 1
    I'm not sure StringBuilder would help here - in the current form (string concatenation in a single statement) this code will be translated as a single String.Concat call. – Hans Kesting Jul 13 '16 at 13:46
  • @HansKesting Thanks for the edit - and thanks for the note on `String.Concat` - I wasn't aware of that, something for me to go read up on...! – James Thorpe Jul 13 '16 at 14:01
1

I suggest extracting methods for this

  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)
    : ""; 

With just two methods extracted the code turns into one far more readable and thus easier to debug. Do not repeat yourself.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
0

Likely even the compiler is confused by those long "? :". I would write a simple extension method with expression.

    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);
    }

It checks if the property is null as well. Then the code will be cleaner and more readable:

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

ws.Rows[index].Cells[24].Value = value;
Stephen Zeng
  • 2,748
  • 21
  • 18