使用类和接口定义通用对象

时间:2012-05-11 15:13:19

标签: c# generics inheritance

我在查找如何在使用通用对象时要求类扩展了接口时遇到了一些麻烦。我发现这很难解释,但我希望能够要求一个班级&创建我的通用对象时的接口。

我已经创造了我能想到的最简单的版本 - 希望能够比我更好地解释我的问题。

abstract class Base
{}
class Class1 : Base, IComparable<Base>
{
    public int CompareTo(Base other)
    {
        return GetHashCode().CompareTo(other.GetHashCode());
    }
}
class Class2 : Base, IComparable<Base>
{
    public int CompareTo(Base other)
    {
        return GetHashCode().CompareTo(other.GetHashCode());
    }
}
class Class3 : Base
{}
class Program
{
    // This list should only accept objects that extend (Base & IComparable<Base>)
    public static List<Base> BigList = new List<Base>();

    static void Main(string[] args)
    {
        Class1 c1 = new Class1();
        Class2 c2 = new Class2();
        Class3 c3 = new Class3();
        BigList.Add(c1);
        BigList.Add(c2);
        // This should not be allowed because Class3 does not extend IComparable<Base>
        BigList.Add(c3);

        Check(new Class1());
    }
    public static void Check(Base bb)
    {
        foreach (Base b in BigList)
        {
            // Assert that this is true
            IComparable<Base> c = (IComparable<Base>)b;

            if (c.CompareTo(bb) < 0)
                Console.WriteLine("Less Than");
            else if (c.CompareTo(bb) == 0)
                Console.WriteLine("Equal");
            else if (c.CompareTo(bb) > 0)
                Console.WriteLine("Greater Than");
        }
    }
}

正如您从代码中的内嵌注释中看到的那样,我希望列表BigList要求添加的对象扩展Base AND 实现{{ 1}}。这不是真正的多重继承,因为它只是一个类(和一个接口)。

有谁知道这样做的方法?

修改

感谢大家的评论。基本上答案有两种:创建中级类,或使用IComparable<Base>。 #2不是一个选项,因为我们确实需要Base中的逻辑。 #1是最可行的选择,也是我们勉强的选择。这种方法的关注点是它将在实际的类层次结构中添加的混乱和复杂程度。

无论C#不会让我们做我们想做的事情,我们都必须使用中间类。谢谢大家。

4 个答案:

答案 0 :(得分:7)

这个怎么样:

abstract class Base {
}

abstract class Intermediate : Base, IComparable<Base> {
}

class Class1 : Intermediate {
}

class Class2 : Intermediate {
}

class Class3 : Base {
}

public static List<Intermediate> BigList = new List<Intermediate>();
BigList.Add(new Class1()); // ok
BigList.Add(new Class2()); // ok
BigList.Add(new Class3()); // error

当然,只有当您需要实现Base而不是IComparable<Base>的类时,才需要这样做,否则您只需将Base声明为

abstract class Base : IComparable<Base> {
}

答案 1 :(得分:0)

为什么不创建另一个继承基类并实现IComparable的类?

public class ComparableBase :Base, IComparable<Base>
{
....
}

class Class2 : ComparableBase 
{
    public int CompareTo(Base other)
    {
        return GetHashCode().CompareTo(other.GetHashCode());
    }
}

public static List<ComparableBase > BigList = new List<ComparableBase >();

答案 2 :(得分:0)

如果您将BigList设置为List<IComparable<Base>>,那么您应该获得在Check方法中显示的行为。

public static List<IComparable<Base>> BigList = new List<IComparable<Base>>();
static void Main(string[] args)
{
    Class1 c1 = new Class1();
    Class2 c2 = new Class2();
    Class3 c3 = new Class3();
    BigList.Add(c1);
    BigList.Add(c2);
    // This will now cause a compile error
    // BigList.Add(c3);

    Check(new Class1());
}

public static void Check(Base bb)
{
    foreach (IComparable<Base> c in BigList)
    {
        if (c.CompareTo(bb) < 0)
            Console.WriteLine("Less Than");
        else if (c.CompareTo(bb) == 0)
            Console.WriteLine("Equal");
        else if (c.CompareTo(bb) > 0)
            Console.WriteLine("Greater Than");
    }
}

答案 3 :(得分:0)

IMO,实施没有中间类可以这样做:

abstract class Base{}

class Class1 : Base, IComparable<Base>{}

class Class2 : Base, IComparable<Base>{}

class Class3 : Base{}

var BigList = new List<IComparable<Base>>();

BigList.Add(new Class1());
BigList.Add(new Class2());
BigList.Add(new Class3()); // error

你可以比较:

public static void Check(Base BB){
 foreach (var c in BigList)
    {
        if (c.CompareTo(bb) < 0)
            Console.WriteLine("Less Than");
        else if (c.CompareTo(bb) == 0)
            Console.WriteLine("Equal");
        else if (c.CompareTo(bb) > 0)
            Console.WriteLine("Greater Than");
    }
}