4

我从另一个 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>'.

这里到底出了什么问题?

4

3 回答 3

9

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

只需重复可比较的约束:

public class Ranges<T> where T : IComparable<T>
{
}
于 2013-08-08T17:50:34.047 回答
8

如果你稍微重写你的第二节课,你会明白为什么:

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

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

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

更重要的是,您有一个递归的通用参数!

如果Uis Range<U>,那么您的班级看起来像Ranges<Range<T>>where Tis U,依此类推。

据我所知,你不想写:

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

反而:

Ranges<int> x = ...;

这意味着:

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

    ...
于 2013-08-08T17:50:21.390 回答
1

你不需要新的类,使用 linq。

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

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

所以有效地你有列表的列表。或更一般IEnumerableIEnumerables.

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

   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 包装在新类中。

于 2013-08-08T17:51:27.157 回答