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

时间:2013-08-08 17:44:05

标签: 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);
        }
    }

但是,我希望创建另一个包含此类的许多实例的类,并且可以对它们执行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;
        }
    }

但是,我收到错误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>'.

这到底出了什么问题?

3 个答案:

答案 0 :(得分:9)

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

重复相似的约束:

public class Ranges<T> where T : IComparable<T>
{
}

答案 1 :(得分:8)

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

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

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

错误告诉您编译器不知道U是否可以转换为IComparable<U>,这可以从Ranges<U>Range<T>的声明中明显看出({{1没有实现任何接口)。

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

如果Range<T>U,那么您的课程似乎Range<U>,其中Ranges<Range<T>>T,依此类推。

据我所知,你不打算写:

U

而是:

Ranges<Range<int>> x = ...;

这意味着:

Ranges<int> x = ...;

答案 2 :(得分:1)

您不需要新的类,请使用linq。

list1.All(x=>list2.Any(y=>y == x))

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

如此有效地列出了清单。或者更为一般IEnumerable IEnumerables

有足够的标准通用数据结构来处理这种情况

   public static class ListOfListExtention {

        public static bool ContainAny( this List<List<int>> lists, int number ) {
             return lists.Any(l=>l.Any(x=>x == number))
        }

   }

可以使用IComparable接口以更通用的方式重写

   public static class ListOfListExtention {

        public static bool ContainAny<T>
           (this List<List<int>> lists, int value ) where T : IComparable<T> {
             return lists.Any(l=>l.Any(x=>x == value))
        }

   }

因此,为了与已接受的答案进行比较,如果您只有一个扩展方法,为什么要将List包装在新类中。