C# - 没有从'T'到'System.IComparable <T>'的隐式引用转换

dan*_*oks 4 c# generics

我从另一个SO问题中选择了以下课程:

    public class Range<T> where T : IComparable<T>
    {
        public T Minimum { get; set; }
        public T Maximum { get; set; }

        public override string ToString() { return String.Format("[{0} - {1}]", Minimum, Maximum); }

        public Boolean IsValid() { return Minimum.CompareTo(Maximum) <= 0; }

        public Boolean ContainsValue(T value)
        {
            return (Minimum.CompareTo(value) <= 0) && (value.CompareTo(Maximum) <= 0);
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是,我想创建另一个包含此类的许多实例的类,并且可以对它们执行foreach循环,如果传递的数字包含在任何一个范围中,则返回true:

    public class Ranges<T> where T : Range<T>
    {
        private List<Range<T>> rangelist;

        public void add(Range<T> range)
        {
            rangelist.Add(range);
        }

        public Boolean ContainsValue(T value)
        {
            foreach (Range<T> range in rangelist)
            {
                if (range.ContainsValue(value)) return true;
            }

            return false;
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是,我收到了错误 The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Range<T>'. There is no implicit reference conversion from 'T' to 'System.IComparable<T>'.

这究竟出了什么问题?

Hen*_*man 9

您似乎不需要约束 where T : Range<T>

只需重复相似的约束:

public class Ranges<T> where T : IComparable<T>
{
}
Run Code Online (Sandbox Code Playgroud)


use*_*116 8

如果你略微改写你的第二堂课,你会明白为什么:

public class Ranges<U> where U : Range<U>
{
    private List<Range<U>> rangelist;

    public void add(Range<U> range)
    {
        rangelist.Add(range);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

该错误告诉您编译器不知道是否U可转换为IComparable<U>,这从声明Ranges<U>Range<T>(Range<T>并未实现任何接口)中显而易见.

更重要的是,你有一个递归的泛型参数!

如果URange<U>,那么你的班级就像是Ranges<Range<T>>在哪里,依此类推.TU

据我所知,你不打算写:

Ranges<Range<int>> x = ...;
Run Code Online (Sandbox Code Playgroud)

反而:

Ranges<int> x = ...;
Run Code Online (Sandbox Code Playgroud)

这意味着:

public class Ranges<T> where T : IComparable<T>
{
    private List<Range<T>> rangelist;

    ...
Run Code Online (Sandbox Code Playgroud)