Selecting a thumbnail from among a large, medium, and small image I'm parsing some data in C# where I have an object with 3 properties: "large", "medium", "small"; each property may contain a string array with an image path, and I'm trying to extract that path.

The data should always have a large image, but not always a medium or small. I'm trying to generate thumbnail images, so I prefer the small, but if it's not there I want the medium, otherwise the large. The following code works and I understand it but I have the feeling there's a more expressive way:

var thumb = (images == null)
            ? null
            : (images.small == null) || (images.small.Length == 0)
                ? (images.medium == null) || (images.medium.Length == 0)
                    ? (images.large == null) || (images.large.Length == 0)
                        ? null
                        : images.large[0]
                    : images.medium[0]
                : images.small[0];


I could at least break out the guard clauses to a Boolean method like hasImage("small") or better yet hasImage(imageEnum.SMALL) -- that would make the tests easier to understand and also encapsulate them so changes to the test logic wouldn't pollute the retrieval logic.

Other than that, is there a better (i.e. easier to understand) way to express the overall algorithm?
var thumb = (images == null)
            ? null
            : (images.small == null) || (images.small.Length == 0)
                ? (images.medium == null) || (images.medium.Length == 0)
                    ? (images.large == null) || (images.large.Length == 0)
                        ? null
                        : images.large[0]
                    : images.medium[0]
                : images.small[0];

  
  I understand it but


no one else does ;-) 

Ternary operators are very usefull but you really exaggerated. In a production code I would never accept it.

You should break it to smaller pieces.


  is there a better (i.e. easier to understand) way to express the overall algorithm?


There might be. If the images type is under your control then you could implement the IEnumerable interface on it and return the sub-image collections:

class ImageCollection : IEnumerable&lt;Bitmap[]&gt;
{
    public Bitmap[] small { get; set; }
    public Bitmap[] medium { get; set; }
    public Bitmap[] large { get; set; }

    public IEnumerator&lt;Bitmap[]&gt; GetEnumerator()
    {
        yield return small;
        yield return medium;
        yield return large;
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}


Then with a small helper lambda you can encapsulate the first-image-or-default logic and use linq to retrieve the first image found:

var images = new ImageCollection();
var getFirstImageOrDefault = new Func&lt;Bitmap[], Bitmap&gt;(
    bitmaps =&gt; bitmaps == null ? null : bitmaps.FirstOrDefault());
var thumb = images.Select(getFirstImageOrDefault).FirstOrDefault(bitmap =&gt; bitmap != null);