如何使一个抽象基类IComparable不比较两个单独的继承类?

Dro*_*ogo 8 .net c# generics inheritance

(C#,VS2008)在我正在研究的程序中,我有很多对象都具有ID并实现IComparable,因此各种对象的List <> - s可以通过ID轻松搜索.由于我讨厌复制/粘贴代码,我认为我会将这些功能抽象到基类,如下所示:

using System;

namespace MyProg.Logic
{
    abstract class IDObject : IComparable<IDObject> 
    {
        private int miID;

        public int ID
        {
            get { return miID; }
            set { miID = value; }
        }

        public IDObject(int ID)
        {
            miID = ID;
        }

        #region IComparable<IDObject> Members

        int IComparable<IDObject>.CompareTo(IDObject other)
        {
            return miID.CompareTo(other.miID);
        }

        #endregion
    }
}
Run Code Online (Sandbox Code Playgroud)

我看到的缺点是每个继承它的两个单独的类可以直接使用.CompareTo()进行比较,我希望强制每个继承自IDObject的类只能与完全相同类的其他类相比较.所以我希望弄清楚如何做到这一点,并想出了这个

using System;

namespace MyProg.Logic
{
    abstract class IDObject : IComparable<T> where T : IDObject
    {
        private int miID;

        public int ID
        {
            get { return miID; }
            set { miID = value; }
        }

        public IDObject(int ID)
        {
            miID = ID;
        }

        #region IComparable<T> Members

        int IComparable<T>.CompareTo(T other)
        {
            return miID.CompareTo(other.miID);
        }

        #endregion
    }
}
Run Code Online (Sandbox Code Playgroud)

但是这给出了编译错误"非泛型声明中不允许约束"

看看它,我确信有一种方法可以做类似的事情,这样每个类只能与同一个类的其他实例相媲美,但我无法梳理出语法.

Nic*_*era 12

您可以使用奇怪的重复模板模式来解决此问题.

abstract class Base<T> : IComparable<T> where T : Base<T> {
    public int Rank { get; set; } // Order instances of derived type T by Rank
    public int CompareTo(T other) { return Rank.CompareTo(other.Rank); }
}
class Foo : Base<Foo> {}
class Bar : Base<Bar> {}

static class Program {
   static void Main() {
       var foo1 = new Foo { Rank = 1 };
       var foo2 = new Foo { Rank = 2 };
       var bar1 = new Bar { Rank = 1 };
       var bar2 = new Bar { Rank = 2 };

       Console.WriteLine(foo1.CompareTo(foo2));
       Console.WriteLine(bar2.CompareTo(bar1));

       //error CS1503: Argument '1': cannot convert from 'Bar' to 'Foo'
       //Console.WriteLine(foo1.CompareTo(bar1));
   }
}
Run Code Online (Sandbox Code Playgroud)