Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# declare both, class and interface

// interface
public interface IHasLegs { ... }

// base class
public class Animal { ... }

// derived classes of Animal
public class Donkey : Animal, IHasLegs { ... } // with legs
public class Lizard : Animal, IHasLegs { ... } // with legs
public class Snake : Animal { ... } // without legs

// other class with legs
public class Table : IHasLegs { ... }

public class CageWithAnimalsWithLegs {
    public List<??> animalsWithLegs { get; set; }
}

What should I put in the ?? to force objects that inherit from both Animal and IHasLegs? I don't want to see a Snake in that cage neither a Table.

-------------- EDIT --------------

Thank you all for your answers, but here is the thing: What I actually want to do is this:

public interface IClonable { ... }
public class MyTextBox : TextBox, IClonable { ... }
public class MyComboBox : ComboBox, IClonable { ... }

TextBox/ComboBox is of course a Control. Now if I make an abstract class that inherits both Control and IClonable, I will loose the TextBox/ComboBox inheritance that I need. Multiple class inheritance is not allowed, so I have to work with interfaces. Now that I think of it again, I could create another interface that inherits from IClonable:

public interface IClonableControl : IClonable { ... }
public class MyTextBox : TextBox, IClonableControl { ... }
public class MyComboBox : ComboBox, IClonableControl { ... }

and then

List<IClonableControl> clonableControls;

Thank you!!

like image 996
Stefanos Kargas Avatar asked Oct 29 '13 14:10

Stefanos Kargas


Video Answer


4 Answers

First of all, Animals is a bad choice for a class name, it would be Animal. Class names should be in singular. This class should also be declared abstract, because it is just a base class for concrete types such as Donkey.

Second, you can define an abstract class named LeggedAnimal that inherits from Animal and IHasLegs. And then you can inherit Donkey from LeggedAnimal, etc.

Finally, you can then say List<LeggedAnimal> and you're good to go!

like image 87
Roy Dictus Avatar answered Sep 20 '22 07:09

Roy Dictus


There is no direct concept of a List<T where T : Animals, IHasLegs>. You can move the T up a level, to the cage - but then the caller must specify an individual T that satisfies both constraints:

class Cage<T> where T : Animal, IHasLegs {
    public List<T> Items {get;set;}
}

It could be a Cage<Lizard>, for example - or (separately) a Cage<Donkey> - but you still could not use this to store any Animal that has legs - i.e. you couldn't put a Lizard and a Donkey in the same cage using this concept.

like image 39
Marc Gravell Avatar answered Sep 22 '22 07:09

Marc Gravell


Why Don't you make a class AnimalwithLegs?

public abstract class AnimalWithLegs : Animal, IHasLegs{}

then

public class CageWithAnimalsWithLegs 
{
   public List<AnimalWithLegs>  AnimalWithLegs { get; set; }
}
like image 34
gsharp Avatar answered Sep 19 '22 07:09

gsharp


  1. I think that Animal is an abstract class and hence needs to be called IAnimal.
  2. Create a new type IAnimalWithLegs that inherits from both IhasLegs and IAnimal.
  3. Use the newly created type as the type of the list.
like image 31
user844541 Avatar answered Sep 20 '22 07:09

user844541