开发者

Return a generic nullable Element

I'm trying to make a method that returns the highest value of an Array with generic elements that can开发者_如何转开发 be 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 
    // ****
}

What is the proper way to return the value?


Nullable.GetValueOrDefault


You can simplify your method:

public T Greatest<T>(T?[] array) where T : struct, IComparable<T> 
{
    return array.Max().GetValueOrDefault();
}


You can simply change the method to return T? and then return Greater. If the greatest value isn't a value at all, why pretend that it is? On the other hand, if you really need to return some kind of non-nullable value, then you can do

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

However, defining a default that is appropriate for all types T would be difficult, so you can also rely on the automatic default of the type.

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

Which is the functional equivalent of

if (Greater.HasValue)
    return Greater.Value;
else 
    return default(T);


To get your method to compile, you could pull the default.

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

That said, if you're using a modern version of C#, you should not be writing this method in the first place and should instead be using Enumerable.Max().


OP said

What is the properly [sic] way to return the Value?

The proper way is to not reinvent the wheel:

public T Greatest<T>( IEnumerable<T?> list ) where T : struct, IComparable<T> 
{
    return list.Where(  x => x.HasValue )
               .Select( x => x.Value    )
               .Max()
               ;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜