c# - How to use interface as a method parameter but still access non-interface methods? -


i've spent hours trying find way implement , far haven't found solution, i'm hoping please point me in right direction.

i have c# winforms project has abstract base class several child classes. of methods same each child class has few additional methods specific it.

i want able declare type of class being used once , pass type other methods without having manually check type everywhere going "if class type=a else if class type=b that, , on".

the problem need pass base class or interface accomplish this. however, doing means can no longer access properties or methods specific child classes , don't know how fix/workaround this.

here's simplified example of i'm trying do:

interface , class structure

public interface ianimal     {         string nameofanimal { get; set; }          void eat();     }  public abstract class animal : ianimal     {         public abstract string nameofanimal { get; set; }          public abstract void eat();     }  public class bird : animal {     public bird()     {         nameofanimal = "bob bird";         numberoffeathers = 100;     }      // interface members     public override string nameofanimal { get; set; }      public override void eat()     {         system.windows.forms.messagebox.show("eating bird");     }      // bird specific properties , methods     public int numberoffeathers { get; protected set; }     public string someotherbirdspecificproperty { get; protected set; }      public void fly()     {         // fly bird     } }  public class fish : animal {     public fish()     {         nameofanimal = "jill fish";         doesfishhavesharpteeth = true;     }      // interface members     public override string nameofanimal { get; set; }      public override void eat()     {         system.windows.forms.messagebox.show("eating fish");     }      // fish specific properties     public bool doesfishhavesharpteeth { get; protected set; }     public string someotherfishspecificproperty { get; protected set; } } 

main form code

    private void button1_click(object sender, eventargs e)     {         ianimal mycustomanimal = null;         string animaltheuserselected = "bird";          // want manually specify once         switch (animaltheuserselected)         {             case "bird":                 mycustomanimal = new bird();                 break;              case "fish":                 mycustomanimal = new fish();                 break;              default:                 break;         }          dosomethingwithacustomanimal(mycustomanimal);     }      private void dosomethingwithacustomanimal(ianimal myanimal)     {         // works fine         messagebox.show(myanimal.nameofanimal);         myanimal.eat();          // doesn't work         messagebox.show(myanimal.numberoffeathers);         myanimal.fly();     } 

i understand why i'm having issue in main form code... compiler doesn't know type of animal being passed yet doesn't know show. however, don't know should fix this.

i've tried:

  • putting animal-specific properties in interface. works violates several oop principles. fish doesn't have feathers, etc. these specific properties don't belong there.

  • manually checking type everywhere going "if type=fish abc else if type=bird def". works violates dry principle because i'm repeating myself everywhere. lot of methods using animals, nightmare maintain in future.

  • explicitly casting ianimal specific animal ((bird)mycustomanimal).numberoffeathers. works don't know cast use @ compile-time. won't known until user selects animal @ run-time.

so i'm wondering how can solve issue?

more specifically, i'm wondering how can re-design above code can both:

a) explicitly declare type of animal once , pass type everywhere (without having lots of manual checks in every method see type before doing it)

and also

b) somehow still have way manually access animal-specific properties somebird.numberoffeathers when need to.

any ideas?

it depends on trying , hoping achieve. things you've tried far possible approaches, without more context it's hard give general answer. depends on right level of abstraction trying do.

one thing remember can have class implement many interfaces need. like:

public interface ianimal {     string nameofanimal { get; set; }     void eat(); }  public interface ifly {     void fly(); }  public interface ihavefeathers {     int numberoffeathers { get; set; } } 

then bird class can be:

public bird : animal, ifly, ihavefeathers {     // implementation } 

and in method can like:

private void dosomethingwithacustomanimal(ianimal myanimal) {     // works fine     messagebox.show(myanimal.nameofanimal);     myanimal.eat();      var feathered = myanimal ihavefeathers;     if (feathered != null)     {         messagebox.show(feathered.numberoffeathers);     }      var flier = myanimal ifly;     if (flier != null)     {         flier.fly();     } } 

the other thing think how abstract need higher level. need fly, why? happens animal can't fly? fly trying move? perhaps do:

public interface ianimal {     string nameofanimal { get; set; }     void eat();     void move(); } 

and in bird can this:

public bird : animal, ifly, ihavefeathers {     public override void move()     {         fly();     }      public void fly()     {         // flying implementation     }     // rest of implementation... } 

Comments