2012-05-11 2 views
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 требовать, чтобы объекты добавляются расширить BaseИ реализует IComparable<Base>. На самом деле это не множественное наследование, потому что это только один класс (и интерфейс).

Кто-нибудь знает, как это сделать?

EDIT

Спасибо за комментарии всех. В основном ответы приходят в двух вариантах: создайте промежуточный класс или используйте List<IComparable<Base>>. # 2 - это не вариант, потому что в базе есть логика, которая нам действительно нужна. # 1 - самый жизнеспособный вариант, и тот, который мы неохотно, идущий с. Забота об этом подходе заключается в количестве беспорядка и сложности, которые будут добавлены в фактическую иерархию классов.

Независимо от того, если C# не позволит нам делать то, что мы хотим сделать, нам придется делать это с промежуточными классами. Всем спасибо.

+1

То, что вы хотите, не представляется возможным без создания вашего собственную структуру данных, реорганизацию иерархии классов или создание вспомогательного метода Add(). Почему бы вам не сделать свой BigList типа List >()? – Osiris

+0

// Это не должно допускаться, потому что Class2 не расширяет IComparable >>> class Class2: Base, IComparable er я ненавижу его разбивать, но класс 2 действительно расширяет его;) класс 3, однако, не – RhysW

+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> { 
} 
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 >(); 
0

Если вы установите ваш BigList быть List<IComparable<Base>>, который должен получить информацию о поведении вашего отображающее в вашем метод проверки.

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"); 
    } 
} 
0

ИМО, реализация без промежуточного класса можно сделать так:

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"); 
    } 
} 
+0

Но я мог бы создать класс, который не наследуется от Base и который может быть сохранен в списке: class NoBase: ICombarable {}. Я думаю, что это побеждает одно из его условий. – user957902

Смежные вопросы