开发者

Initializing C# generics using type-specific values

In the following class:

public class Example<T> where T : IComparable {
    private T _min;
    private T _max;

    public Example() {
        // _min = T.MinValue;
        // _max = T.MaxValue;
    }

    public Example(T min, T max) {
        _min = min;
        _max = max;
    }

    public bool Contains(T val) {
        return (val.CompareTo(_min) < 0) && (val.CompareTo(_max) > 0);
    }
}

What would be the best way to开发者_JAVA百科 initialize the members to their type-specific min & max values in the default constructor? I know this puts another constraint on the allowed types for the generic, but that's fine for my purposes.

Additionally, if a type supported infinite values, such as float or double, is there a way to detect this and set the values accordingly?


There's no constraint that would allow you to do get a MinValue and MaxValue. The only value you can get in a strong-typed way is the default (default(T)).

If you know that the types will have static MinValue and MaxValue properties, you can get at these using Reflection, but could not enforce the safety of this at compile time.

An alternative solution would be to redesign your class slightly: add _isMinSpecified and _isMaxSpecified boolean members, and consult these in your Contains method -- e.g. if neither a min nor a max had been specified, you would always return true.


Well, I don't think there is an interface available out of the box which could help you. Each concrete type (Int32, float, etc) defines their own min and max values, and they share no common interface for something like this. You could of course define a wrapper class yourself which would accomplish this, but then the there is no reason to use generics at all :)

Additionally, if a type supported infinite values, such as float or double, is there a way to detect this and set the values accordingly?

There is no such thing as an "infinite value" as far as a computer is concerned, and floating point numbers are no more "infinite" than a bit is (they just have more of them).


There is no generic way to know the min and max value for a type. It may not even make sense, depending on the kind of data you're talking about... It is possible to use reflection to find MinValue and MaxValue static members on the type, but these member are not defined on all types.


If you are using C# 3.5, here is an example of using reflection to solve this issue:

public static class GenericLimit<T>
{
    public static readonly T MinValue = (T)MinValue.GetType ().GetField ("MinValue").GetValue (MinValue);
    public static readonly T MaxValue = (T)MaxValue.GetType ().GetField ("MaxValue").GetValue (MaxValue);
}

public class MinMax<T> where T : struct
{
    private readonly T minValue = GenericLimit<T>.MinValue;
    private readonly T maxValue = GenericLimit<T>.MaxValue;

    public T Min { get; private set; }
    public T Max { get; private set; }

    public static bool InRange (T value, T min, T max)
    {
        return (Operator.GreaterThanOrEqual (value, min) && Operator.LessThanOrEqual (value, max));
    }

    public MinMax () { Reset (); }

    public void Update (T n)
    {
        if (Operator.LessThan (n, Min)) Min = n;
        if (Operator.GreaterThan (n, Max)) Max = n;
    }

    public void Reset ()
    {
        Min = maxValue;
        Max = minValue;
    }
}

The generic math is from C# in Depths to (thanks to Jon Skeet and Marc Gravell).

PS Any suggestions for simplifying the reflection will be greatly appreciated.


public Example() {
    _min = default (T);
    _max = default (T);
}

sorry, that's not what you're looking for.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜