У меня есть класс, который позволяет мне устанавливать значение с минимальными и максимальными пределами. Если эти пределы превышены, значение изменяется. До сих пор я использовал только тип данных double, но я также хочу использовать целые числа. Я надеялся, что универсальный класс даст правильное решение, но столкнулся с некоторыми проблемами ....

/// <summary>
/// This method takes a default value with the min and max limits. If the value exceeds these limits it is corrected.
/// </summary>
public partial class GeneratorProperty<T>
{
    private T _value;

    private T Min { get; }

    private T Max { get; }

    /// <summary>
    /// </summary>
    /// <param name="defaultValue"></param>
    /// <param name="min"></param>
    /// <param name="max"></param>
    public GeneratorProperty(T defaultValue, T min, T max)
    {
        _value = defaultValue;
        Min = min;
        Max = max;
    }

    /// <summary>
    /// </summary>
    public T Value
    {
        get { return _value; }
        set
        {
            if (typeof (T) == typeof (double))
            {
                var temp = (double)(object)value;
                (double)(object)_value = temp.ConstrainDouble((double)(object)Min, (double)(object)Max);
                //Cannot modify the result of an unboxing conversion
            }
            else if (typeof(T) == typeof(int))
            {
                var temp = (int)(object)value;
                (int)(object)_value = temp.ConstrainInt((int)(object)Min, (int)(object)Max);
                //Cannot modify the result of an unboxing conversion
            }
        }
    }
}

/// <summary>
/// </summary>
public static class Extention
{
    /// <summary>
    ///     The extension method Constrains a double using a min and max value.
    /// </summary>
    /// <param name="value">Value to test</param>
    /// <param name="min">minimum limit</param>
    /// <param name="max">maximum limit</param>
    /// <returns></returns>
    public static double ConstrainDouble(this double value, double min, double max)
    {
        if (value >= min && value <= max)
            return value;
        if (value >= max)
            return max;
        if (value <= min)
            return min;
        return 1;
    }

    public static double ConstrainInt(this int value, int min, int max)
    {
        if (value >= min && value <= max)
            return value;
        if (value >= max)
            return max;
        if (value <= min)
            return min;
        return 1;
    }
}

Во время установки значения T я хотел бы ограничить его типом данных. Однако приведение к правильному типу данных вызывает у меня проблемы? Если честно, я новичок в дженериках.

Кто-нибудь, у кого есть совет или лучший подход к решению этой проблемы?

0
JR_ 27 Фев 2016 в 02:38
Возможно _value = (T) (object) temp.ConstrainDouble ((double) (object) Min, (double) (object) Max); работает?
 – 
Gusman
27 Фев 2016 в 02:42
1
Вероятно, вам следует просто сделать код полностью универсальным. Ограничьте T значением IComparable<T> и используйте CompareTo для сравнения вместо операторов.
 – 
Mike Zboray
27 Фев 2016 в 02:47
Объяснение ошибки - stackoverflow.com/questions/17280547/…
 – 
Alexei Levenkov
27 Фев 2016 в 03:25

1 ответ

Лучший ответ

Каждый раз, когда вы выполняете проверку определенного типа для универсального типа (т.е. if (typeof (T) == typeof (double))), вы, вероятно, делаете что-то не так.

public partial class GeneratorProperty<T> where T: IComparable<T>
{
    ...
    public T Value
    {
        get {... }
        set 
        {
            if (this.Max.CompareTo(value) < 0)
                this._value = this.Max;
            else if (this.Min.CompareTo(value) > 0)
                this._value = this.Min;
            else
                this._value = value;
        }
    }
}

Одна из основных целей дженериков - избежать заботы о том, какие типы вы на самом деле получаете и с которыми работаете. Ограничения помогают сузить круг вопросов, указав части типа, которые необходимы для правильной работы.

В этом случае вам нужна возможность сравнивать их, поэтому сделайте это в своем ограничении.

7
Chris Hannon 27 Фев 2016 в 02:58
1
CompareTo должен возвращать только отрицательное значение, если оно меньше, и положительное, если оно больше, а не 1 или -1.
 – 
Lee
27 Фев 2016 в 02:57
Хороший улов, забыл об этом.
 – 
Chris Hannon
27 Фев 2016 в 02:58