4

ジェネリック オブジェクトを操作するときに、クラスがインターフェイスを拡張したことを要求する方法を理解するのに苦労しています。これを説明するのは難しいと思いますが、ジェネリック オブジェクトを作成するときにクラスとインターフェイスを要求できるようにしたいと考えています。

私が考えることができる最も単純なバージョンを作成しました。うまくいけば、それが私の問題をよりよく説明するでしょう。

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追加するオブジェクトが extends Base AND implementsであることをリストで要求したいと思いますIComparable<Base>。ただし、これはただ 1 つのクラス (およびインターフェイス) であるため、多重継承ではありません。

これを行う方法を知っている人はいますか?

編集

コメントありがとうございます。基本的に答えは 2 種類あります: 中間クラスを作成するか、List<IComparable<Base>>. 実際に必要なロジックが Base にあるため、#2 はオプションではありません。#1は最も実行可能なオプションであり、私たちがしぶしぶ行っているオプションです. このアプローチの懸念は、実際のクラス階層に追加される混乱と複雑さです。

C# でやりたいことを実行できない場合でも、中間クラスで実行する必要があります。みんな、ありがとう。

4

4 に答える 4

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> {
}
于 2012-05-11T15:19:22.533 に答える
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");
    }
}
于 2012-05-11T15:24:38.313 に答える
0

base を継承し、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 >();
于 2012-05-11T15:22:31.823 に答える
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");
    }
}
于 2012-05-11T15:28:05.070 に答える