Ошибка перечисления в C # с обобщениями - PullRequest
5 голосов
/ 23 июня 2009

Я не понимаю, что здесь происходит ...

Я получил следующую ошибку: Тип 'TestApp.TestVal' нельзя использовать в качестве параметра типа 'T' в универсальном типе или методе 'TestApp.SomeClass<T>'. Там нет конвертации бокса от 'TestApp.TestVal' до 'System.IComparable<TestApp.TestVal>'.

Эта ошибка возникает для следующего кода:

public enum TestVal
{
    First,
    Second,
    Third
}

public class SomeClass<T>
    where T : IComparable<T>
{
    public T Stored
    {
        get
        {
            return storedval;
        }
        set
        {
            storedval = value;
        }
    }
    private T storedval;
}

class Program
{
    static void Main(string[] args)
    {
        //Error is on the next line
        SomeClass<TestVal> t = new SomeClass<TestVal>(); 
    }
}

Поскольку enum по умолчанию int, а int реализует интерфейс IComparable<int>, похоже, что ошибки не должно быть ...

Ответы [ 4 ]

8 голосов
/ 23 июня 2009

Во-первых, я не уверен, имеет ли смысл использовать IComparable<T> с перечислением ... IEquatable<T>, конечно - но сравнение?

как более безопасная альтернатива; вместо того, чтобы указывать IComparable<T> с общим ограничением, возможно, используйте Comparer<T>.Default внутри класса. Это имеет преимущество поддержки IComparable<T> и IComparable - и это означает, что у вас меньше ограничений для распространения.

Например:

public class SomeClass<T> { // note no constraint
    public int ExampleCompareTo(T other) {
        return Comparer<T>.Default.Compare(Stored, other);
    }
    ... [snip]
}

Это прекрасно работает с enum:

SomeClass<TestVal> t = new SomeClass<TestVal>();
t.Stored = TestVal.First;
int i = t.ExampleCompareTo(TestVal.Second); // -1
5 голосов
/ 23 июня 2009

Перечисления не являются производными от System.Int32s - они происходят от System.Enum, который не реализует IComparable<int> (хотя и реализует IComparable).

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

1 голос
/ 23 июня 2009

Enum не реализует IComparable<T>, но он реализует IComparable. Таким образом, перечисление может быть T в предложении where, например:

    where T : IComparable

но это выдает ошибку:

    where T : IComparable<T>

А потом, я думаю, вы хотели бы, чтобы SomeClass был сопоставимым. Чтобы сделать это, он должен был бы реализовать сам IComparable.

Вот пример обоих (использование открытого члена для простоты кода):

public class SomeClass<T>
    : IComparable<SomeClass<T>>
    where T : IComparable
{
    public T storedval;

    public int CompareTo(SomeClass<T> other)
    {
        return storedval.CompareTo(other.storedval);
    }
}
0 голосов
/ 23 июня 2009

В перечислениях C # реализовано IComparable, но не универсальное IComparable<T>. Я не уверен, почему это так, но, возможно, вы могли бы перейти к не универсальному IComparable в вашем предложении where.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...