Вернуть универсальный обнуляемый элемент - PullRequest
1 голос
/ 27 июня 2011

Я пытаюсь создать метод, который возвращает наибольшее значение Array с общими элементами, которые могут быть Nullable.

 public T Greatest<T>(T?[] array) where T : struct, IComparable<T> 
 {
     T? Greater = null;
     foreach (var elem in array)
     {
         if(elem.HasValue)
         {
             if(Greater.HasValue)
             {
                 if(Greater.Value.CompareTo(elem.Value) < 0)
                 {
                     Greater = elem;
                 }
             }
             else
             {
                 Greater = elem;
             }
        }
    }

    //Problem here: What is the best way to return the greatest value?
    // ****
    return Greater.Value; // Possible InvalidOperationException 
    // ****
}

Как правильно вернуть значение?

Ответы [ 5 ]

4 голосов
/ 27 июня 2011

Вы можете упростить свой метод:

public T Greatest<T>(T?[] array) where T : struct, IComparable<T> 
{
    return array.Max().GetValueOrDefault();
}
4 голосов
/ 27 июня 2011
3 голосов
/ 27 июня 2011

Вы можете просто изменить метод, чтобы вернуть T?, а затем вернуть Greater. Если наибольшее значение вообще не является значением, зачем делать вид, что оно есть? С другой стороны, если вам действительно нужно вернуть какое-то необнуляемое значение, то вы можете сделать

if (Greater.HasValue)
    return Greater.Value;
else 
    return /* define your default here */

Однако определить значение по умолчанию, подходящее для всех типов T, будет сложно, поэтому вы также можете рассчитывать на автоматическое значение по умолчанию для типа.

return Greater.GetValueOrDefault(); // returns either Value or default(T)

Что является функциональным эквивалентом

if (Greater.HasValue)
    return Greater.Value;
else 
    return default(T);
0 голосов
/ 27 июня 2011

ОП сказал

Как правильно [sic] вернуть значение?

Правильный способ - не изобретать велосипед:

public T Greatest<T>( IEnumerable<T?> list ) where T : struct, IComparable<T> 
{
    return list.Where(  x => x.HasValue )
               .Select( x => x.Value    )
               .Max()
               ;
}
0 голосов
/ 27 июня 2011

Чтобы ваш метод компилировался, вы можете использовать значение по умолчанию.

return (Greater.HasValue) ?
            Greater.Value :
            default(T);

Тем не менее, если вы используете современную версию C #, вам не следует писать этот метод в первую очередь, а вместо этого следует использовать Enumerable.Max () .

...