How to implement an interface using class member? - c#

I have this dog class:
public class Dog : IBarkable
{
public void Bark()
{
Console.WriteLine("Woof!");
}
}
and i have this human class:
public class Human : IBarkable
{
private Dog _myDog = new Dog();
public void Bark()
{
_myDog.Bark();
}
}
Is there any way that i won't have to implement each function explicitly?
somthing like this:
public class Human : IBarkable (_myDog)
{
private Dog _myDog = new Dog();
}
thanks!

Though there is no features for implementing delegating members in visual studio, resharper provides one.
You're looking for Generating Delegating Members of resharper.

From the logical point of view a Human can not bark. So deriving a human from this interface makes no sense. Instead you should provide at least a getter method returning your dog object.

If you are trying to expose a "pet" of the human, a more flexible and technically correct way would be to abstract the Bark method and make the human expose certain aspects of the "pet". As far as API design goes, it's not very intuitive to have a method "Bark" on a human object. Also to consider: what if the human as a cat, parrot, monkey, and an elephant for pets? In this case, your code as it is becomes difficult to maintain (which I suspect is why you want to "auto-implement" interface methods).
I would suggest a slight refactor of your code into something more like this:
public interface ISpeakingAnimal {
void Speak();
} // end interface IAnimal
public interface IHasPets {
List<ISpeakingAnimal> Pets {get; set;}
bool HasPets();
} // end interface IHasPets
public class Dog : ISpeakingAnimal {
public void Speak() {
Console.WriteLine("Woof");
}
} // end class Dog
public class Cat : ISpeakingAnimal {
public void Speak() {
Console.WriteLine("Meow");
}
} // end class Cat
public class Human : IHasPets {
public Human() {
Name = "The Doctor";
Pets = new List<ISpeakingAnimal>();
} // end constructor
public string Name {get; set;}
public List<ISpeakingAnimal> Pets {get; set;}
public bool HasPets() {
return Pets.Any();
} // end method HasPets
} // end class Human
//Somewhere in your executing code
Human person1 = new Human();
ISpeakingAnimal dog = new Dog();
ISpeakingAnimal cat = new Cat();
person1.Pets.Add(dog);
person1.Pets.Add(cat);
for(int i = 0; i<person1.Pets.Count; i++) {
person1.Pets[i].Speak();
} // end for loop
This encompases several SOLID software development practices, which you can read more about here if you're interested: http://www.blackwasp.co.uk/SOLID.aspx
This design allows you to add new types of pets at any point without having to make changes to Human, or the other animals. and you can add methods to human to interact with it's pets without changing the actual nature of what a human is (since we don't typically bark ;)).

Related

Can i call a method that takes IEnumerable<Baseclass<superclass>> with IEnumerable<Derivedclass<subclass>>

I have some code that's equivalent to this (though this is a simplification):
namespace AnimalHospital
{
public class Animal { }
public class Dog : Animal { }
public class Cat : Animal { }
public interface Vet<T> where T : Animal
{
void takeCareOf(T animal);
}
public abstract class SpecializedDogVet<T> : Vet<T> where T : Dog
{
public abstract void takeCareOf(T dog);
}
public abstract class SpecializedCatVet<T> : Vet<T> where T : Cat
{
public abstract void takeCareOf(T cat);
}
public class AnimalHospital
{
public IList<SpecializedCatVet<Cat>> CatVets = new List<SpecializedCatVet<Cat>>();
public IList<SpecializedDogVet<Dog>> DogVets = new List<SpecializedDogVet<Dog>>();
private void treatSickAnimal(IEnumerable<Vet<Animal>> vets, Animal patient)
{
foreach(var vet in vets)
{
vet.takeCareOf(patient);
}
}
public void treatSickCat(Cat cat)
{
treatSickAnimal(CatVets, cat);
}
public void treatSickDog(Dog dog)
{
treatSickAnimal(DogVets, dog);
}
}
}
I get an error, telling me that conversion from:
IList<SpecializedCatVet<Cat>> to IEnumerable<Vet<Animal>> is not possible. How can this be? Before this they were nonegeneric, and i had some other problems, as i could not override the vet interfaces takeCareOf method. I had expected that as IEnumerable of Animal can easily be instantiated with a list of Dog, the same would be the case with parsing a collection of generics as long as their type parameter is a derirative of the required type. This is not the case though, and I seem unable to figure out why, or how to do this properly.
Thanks for reading.
UPDATE: I'm Accepting JLRishe's answer, makes perfect sense. Thank you very much.
This is not allowed, because if it were allowed, you could something like this:
var cat = new Cat();
treatSickAnimal(DogVets, cat);
And essentially try to force dog vets to treat a cat.
You can remedy this by making your methods generic on the animal parameter:
private void treatSickAnimal<T>(IEnumerable<Vet<T>> vets, T patient) where T : Animal
{
foreach (var vet in vets)
{
vet.takeCareOf(patient);
}
}
This should allow your code to compile correctly and ensure that you don't try to force any dog vets to treat cats.
Side note note - unless you plan on having specialized types (subclasses) of Dog and Cat and vets that are specialized for those subclasses, you can simplify the definition of SpecializedDogVet and SpecializedCatVet to be like this:
public abstract class SpecializedDogVet : Vet<Dog>
{
public abstract void takeCareOf(Dog dog);
}
public abstract class SpecializedCatVet : Vet<Cat>
{
public abstract void takeCareOf(Cat cat);
}
You would then refer to the types like this:
public IList<SpecializedCatVet> CatVets = new List<SpecializedCatVet>();
public IList<SpecializedDogVet> DogVets = new List<SpecializedDogVet>();
You cant because your Vet<T> interface is currently invariant, notice you can make it contravariant by specifying that it is input parameter like so:
public interface Vet<in T> where T : Animal
{
void takeCareOf(T animal);
}
This is possible because everywhere T is used as input parameter.
In order your code to compile you can do what #JLRishe said, or you can change your logic and make T output parameter, but in order to do that you need to change your Vet implementation so everywhere T is used it needs to be in position of output just an example:
public interface Vet<out T> where T : Animal
{
T takeCareOf();
}
So in conclusion, you can pass base class to interfaces or delegates where they have type parameters defined as output and you can pass more derived classes when type parameters are defined as input.
This is actually AMAZING article for covariance and contravariance if I got you hooked you should definitely check it http://tomasp.net/blog/variance-explained.aspx/

What is the logic behind casting classes in c#?

I am trying to understand the logic behind some C# casting conditions for classes, This is my testing code
File: example.cs
public class Animal { public string animal_name = "Animal"; }
public class Dog : Animal { public string dog_name = "Dog"; }
public class Class1
{
public void createObjects()
{
var animal1 = new Animal();
printAnimalName(animal1);
}
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.dog_name);
}
}
In my Main function, I call the call createObjects function as follows:
static void Main(string[] args)
{
Class1 c1 = new Class1();
c1.createObjects();
Console.ReadLine();
}
Running the code above gives an error
System.NullReferenceException:'Object reference not set to an instance of an object'
I understand that this is the way it should be, due to the casting in:
var dog1 = my_animal as Dog;
But what is the logic behind it? Why can't we call the function printAnimalName by passing an Animal object for it? This should be possible as per my understanding, because the function expects an Animal object.
After that var dog1 = my_animal as Dog; // dog1 is of type Dog you need to add only null check:
if(dog1 != null)
{
Console.WriteLine(dog1.dog_name);
}
I think you need to learn about polymorphism, abscract classes and interfaces.
public abstract class FourLeggedAnimal
{
public int GetLegCount()
{
return 4;
}
}
public class Dog : FourLeggedAnimal
{
public string GetScientificName()
{
return "doggus scientificus";
}
}
public class Cat : FourLeggedAnimal
{
public string GetServant()
{
return "human";
}
}
public class AnimalInformer
{
public void DisplayInformation(FourLeggedAnimal animal)
{
Console.WriteLine("It has {0} legs", animal.GetLegCount());
if (animal is Dog)
Console.WriteLine("Its scientific name is {0}", ((Dog)animal).GetScientificName());
if (animal is Cat)
Console.WriteLine("Its servant is {0}", ((Cat)animal).GetServant());
}
}
Here you use the absract class to provide base functionality to all other classes derived from it. All classes derived from FourLeggedAnimal have a method GetLegCount() that returns the number of legs.
But a cat has a servant a dog doesnt have, it just has a friend(both humans, but different relations). So the dog needs no method "GetServant" but the cat does. -> Differenct implementations in 2 seperate classes
Another example with interfaces is that each derived class needs to provide that functionality.
public interface IMovableObject
{
int GetMaxSpeed();
}
public class Car : IMovableObject
{
public int GetMaxSpeed()
{
return 100;
}
}
public class Human : IMovableObject
{
public int GetMaxSpeed()
{
return 20;
}
}
public static class SpeedChecker
{
public static void CheckSpeed(IMovableObject speedster)
{
Console.WriteLine("Checking Speed..");
int speed = speedster.GetMaxSpeed();
if (speed > 50)
Console.WriteLine("It's really fast!");
else
Console.WriteLine("Just a turtle or something similar...");
}
}
Now, if you have a Method getting a IMovableObject that is actually a car, you call the implementation of Car:
Car c = new Car();
Human h = new Human();
Console.WriteLine("Checking Car..");
SpeedChecker.CheckSpeed(c);
Console.WriteLine("Checking Human..");
SpeedChecker.CheckSpeed(h);
-> returns:
Checking Car...
Checking Speed...
It's really fast!
Checking Human...
Checking Speed...
Just a turtle or something similar...
These are 2 uses where you derive classes and use castings to get certain functionality or use the basetype without casting but still getting different functionality
Your problem is here:
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.dog_name); //Animal does not have this property!
}
Casting does not invoke a constructor. This means that dog_name is null, as my_animal does not have a dog_name property. I think you missed something on inheritance here.
This is actually an example that happens in more complex form in the real world; Given class A, B inherits from A. Both have the same properties because of inheritance. Then someone makes a different property with a similar, but not congruous property name and uses it for the same function in the child object. Welcome to code smell city.
To fix your function so it comes across as a dog, you'd do two things:
public class Animal { public string animal_name = "Animal"; }
//since we want a different default, we can
//can make the change in the constructor
public class Dog : Animal
{
Dog(){ this.animal_name = "Dog"; }
//if you really, really want a second name string, you can do this:
public string Dog_Name
{
get { return this.animal_name; }
set { this.animal_name = value; }
}
}
Then, you need to make your method call the appropriate property.
public void printAnimalName(Animal my_animal)
{
var dog1 = my_animal as Dog; // dog1 is of type Dog
Console.WriteLine(dog1.animal_name);
}
I also recommend changing your public fields to properties and possibly override ToString() when all you want to do with an object is return a string representing it.

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

I've spent hours trying to find a way to implement this and so far I haven't found a good solution, so I'm hoping someone could please help point me in the right direction.
I currently have a C# Winforms project that has an abstract base class with several child classes. Most of the methods are the same but each child class has a few additional methods specific to it.
I want to be able to declare a type of the class being used once and pass that type to all my other methods without having to manually check the type everywhere by going "If Class Type=A Do This Else If Class Type=B Do That, and so on".
The problem is that I need to pass the base class or interface to accomplish this. However, by doing so it means I can no longer access the properties or methods specific to the child classes and I don't know how to fix/workaround this.
Here's a simplified example of what I'm trying to do:
Interface and 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 the Bird";
NumberOfFeathers = 100;
}
// Interface members
public override string NameOfAnimal { get; set; }
public override void Eat()
{
System.Windows.Forms.MessageBox.Show("Eating like a Bird");
}
// Bird specific properties and methods
public int NumberOfFeathers { get; protected set; }
public string SomeOtherBirdSpecificProperty { get; protected set; }
public void Fly()
{
// Fly like a bird
}
}
public class Fish : Animal
{
public Fish()
{
NameOfAnimal = "Jill the Fish";
DoesFishHaveSharpTeeth = true;
}
// Interface members
public override string NameOfAnimal { get; set; }
public override void Eat()
{
System.Windows.Forms.MessageBox.Show("Eating like a 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";
// Only want to manually specify this once
switch (animalTheUserSelected)
{
case "Bird":
myCustomAnimal = new Bird();
break;
case "Fish":
myCustomAnimal = new Fish();
break;
default:
break;
}
DoSomethingWithACustomAnimal(myCustomAnimal);
}
private void DoSomethingWithACustomAnimal(IAnimal myAnimal)
{
// This works fine
MessageBox.Show(myAnimal.NameOfAnimal);
myAnimal.Eat();
// This doesn't work
MessageBox.Show(myAnimal.NumberOfFeathers);
myAnimal.Fly();
}
I understand why I'm having that issue in the main form code... the compiler doesn't know which type of animal is being passed to it yet so it doesn't know what to show. However, I don't know what I should do to fix this.
I've tried:
Putting all the animal-specific properties in the interface. This works but violates several OOP principles. A fish doesn't have feathers, etc. so these specific properties don't belong there.
Manually checking the type everywhere by going something like "If Type=Fish do abc Else If Type=Bird do def". This also works but violates the DRY principle because I'm repeating myself everywhere. Also with a lot of methods using animals, this will be a nightmare to maintain in the future.
Explicitly casting IAnimal to a specific animal like ((Bird)myCustomAnimal).NumberOfFeathers. This also works but I don't know what cast to use at compile-time. This won't be known until the user selects an animal at run-time.
So I'm just wondering how I can solve this issue?
More specifically, I'm wondering how I can re-design the above code so that I can both:
A) Explicitly declare a type of animal only once and pass that type everywhere (without having to do lots of manual checks in every method to see what type it is before doing something with it)
and also
B) Somehow still have a way to manually access the animal-specific properties like someBird.NumberOfFeathers when I need to.
Any ideas?
It really depends on exactly what you are trying to do and what you are hoping to achieve. All the things you've tried so far are possible approaches, but without more context it's hard to give a general answer. It depends on what the right level of abstraction is for what you are trying to do.
One thing to remember is that you can have a class implement as many interfaces as you need. So you could do something like:
public interface IAnimal
{
string NameOfAnimal { get; set; }
void Eat();
}
public interface IFly
{
void Fly();
}
public interface IHaveFeathers
{
int NumberOfFeathers { get; set; }
}
Then you Bird class can be:
public Bird : Animal, IFly, IHaveFeathers
{
// implementation
}
And now in a method you can do something like:
private void DoSomethingWithACustomAnimal(IAnimal myAnimal)
{
// This works fine
MessageBox.Show(myAnimal.NameOfAnimal);
myAnimal.Eat();
var feathered = myAnimal as IHaveFeathers;
if (feathered != null)
{
MessageBox.Show(feathered.NumberOfFeathers);
}
var flier = myAnimal as IFly;
if (flier != null)
{
flier.Fly();
}
}
The other thing to think about is how to abstract what you need to a higher level. So you need to Fly, but why? What happens with the Animal that can't fly? By Fly are you really just trying to Move? Then perhaps you could do:
public interface IAnimal
{
string NameOfAnimal { get; set; }
void Eat();
void Move();
}
And in your Bird you can do this:
public Bird : Animal, IFly, IHaveFeathers
{
public override void Move()
{
Fly();
}
public void Fly()
{
// your flying implementation
}
// rest of the implementation...
}
One solution would be to use the visitor pattern to define the operations you want to perform on your animal instances.
First you would define a visitor interface which provides a method for each type of animal you have in your hierarchy.
public interface IAnimalVisitor
{
void VisitBird(Bird bird);
void VisitFish(Fish fish);
}
And then you would need to modify your animal classes and interfaces to include a method which accepts a visitor, like so:
public interface IAnimal
{
string NameOfAnimal { get; set; }
void Accept(IAnimalVisitor visitor);
}
Your actual animal classes now look something like this:
public class Bird : IAnimal
{
public Bird()
{
NameOfAnimal = "Bob the Bird";
NumberOfFeathers = 100;
}
public string NameOfAnimal { get; set; }
public int NumberOfFeathers { get; protected set; }
public void Accept (IAnimalVisitor visitor)
{
visitor.VisitBird(this);
}
}
public class Fish : IAnimal
{
public Fish()
{
NameOfAnimal = "Jill the Fish";
DoesFishHaveSharpTeeth = true;
}
public string NameOfAnimal { get; set; }
public bool DoesFishHaveSharpTeeth { get; protected set; }
public void Accept (IAnimalVisitor visitor)
{
visitor.VisitFish(this);
}
}
Now for anything you want to do with each of your animals you will need to define an implementation of the IAnimalVisitor interface. In your example you displayed message boxes that showed information about the animal so an implementation of the IAnimalVisitor interface that does that could look like this:
public class AnimalMessageBoxes : IAnimalVisitor
{
private void VisitAnimal(IAnimal animal)
{
MessageBox.Show(animal.NameOfAnimal);
}
public void VisitBird(Bird bird)
{
visitAnimal(bird);
MessageBox.Show(bird.NumberOfFeathers);
}
public void VisitFish(Fish fish)
{
visitAnimal(fish);
MessageBox.Show(fish.DoesFishHaveSharpTeeth);
}
}
Now you just need to pass your visitor to your animal and the correct information will be displayed. Your event handling code now looks something like this:
string animalTheUserSelected = "Bird";
IAnimal myCustomAnimal = null;
switch (animalTheUserSelected)
{
case "Bird":
myCustomAnimal = new Bird();
break;
case "Fish":
myCustomAnimal = new Fish();
break;
default:
break;
}
AnimalMessageBoxes msgBoxes = new AnimalMessageBoxes();
myCustomAnimal.Accept(msgBoxes);
If you want to do something else to your animal instances (save them to a file, generate a UI, play sounds...) you just need to define a new IAnimalVisitor implementation that provides your desired behaviour.
For the sake of balance I will say that this might not be an appropriate design as it adds some additional complexity; each 'operation' requires you to implement a visitor and the addition of another animal to your hierarchy requires you to update your visitor interface and all of it's implementations to account for the new case.
Depending on your point of view this can be either good or bad. Some consider the points above to be bad and a reason to avoid the visitor pattern and to use the other methods already suggested. Others (like me) consider the points above to be a good thing; your code will now only compile when you provide an implementation for each animal in your hierarchy and your operations are separated into small, dedicated classes.
My suggestion would be to try the SSCCE I have provided and research the visitor pattern further to decide if this solution is acceptable for your requirements.
I understand, what you are trying to achive, but your approach is just wrong.
Think it this way: does your "Main" class/form realy need to know if there is a bird or a dog? The answer is "NO". There are some common properties which you exposed via an interface (i suggest using a base class here!). Everything else is specific to the given animal. The easiest approach is extending your interface with a DoAnimalSpecificStuff() method - which would perform the specific opperations.
When it comes to presentation, you should take a look at the MVP and MVVM Patterns.
P.S. use a Factory Pattern for animal creation!
You have to explicitly cast the IAnimal object to specific type, if you want to access specific properties/methods.
You can use as operator and then check if the cast was successful like:
Bird b = myAnimal as Bird;
if(b != null)
{
MessageBox.Show(b.NumberOfFeathers);
}

Why can't I access methods specific to my child class?

In C#, I have a parent class with a public member. I want to derive the parent class, then derive the class of the public member, so as to create and access new methods, as follows...
public class Animal { }
public class Sheep : Animal {
public void makeALamb() { }
}
public class Farm
{
public Animal myAnimal;
}
public class SheepFarm : Farm {
public void SheepFarm() {
this.myAnimal = new Sheep();
this.myAnimal.makeALamb();
}
}
This code doesn't compile. "Animal does not contain a definition for makeALamb()". But what I want to do is the essence of polymorphism, no? What am I missing? I'm greatly looking forward to finding out.
Thanks in advance!
Because myAnimal is of type Animal. As such, it can only access members of Animal... and Animal doesn't have a method makeALamb.
The right hand side of the assignment here:
this.myAnimal = new Sheep();
..says what it is. The left hand side says what your code sees it as. The left hand side in your assignment is:
public Animal myAnimal;
// ^^^^^^
Now.. pretend that what you've tried is possible.. consider this:
this.myAnimal = new Snake();
this.myAnimal.makeALamb(); // what does it call here?
this.myAnimal = new Giraffe();
this.myAnimal.makeALamb(); // what here?
..what should happen when you call makeALamb on a Snake instance? ...
If I'm guessing correctly what you're intending to do, consider using generics:
public class Farm<TAnimal> where TAnimal : Animal
{
public TAnimal myAnimal;
}
public class SheepFarm : Farm<Sheep>
{
public void SheepFarm()
{
this.myAnimal = new Sheep();
this.myAnimal.makeALamb();
}
}
makeALamb() is a method of Sheep, not Animal. Sheep derives from Animal, not the other way around.
this.myAnimal is defined as an Animal. Animal does not have a makeALamb method. Since you put a Sheep in this.myAnimal, you could cast it:
((Sheep)this.myAnimal).makeALamb();
This effectively says: "Take this.myAnimal, treat is as a Sheep and call makeALamb() on it". If this.myAnimal is not really a Sheep at run-time, you'll get an exception.
The idea is that your Animal can be instantiated as Sheep, but it will handle only the members defined on Animal. It is as simple as: Sheep is an Animal, but Animal is not a Sheep, so the Animal can not makeALamb() :)
You have to cast your Animal instance to Sheep if you want to access makeALamb method.
public void SheepFarm()
{
this.myAnimal = new Sheep();
((Sheep)this.myAnimal).makeALamb();
}
Without a cast myAnimal is considered as type of Animal and therefore you can only access the members of Animal and the members of base class(es) of Animal (which there is no base class olf Animal in this case).
On the other hand, ofcourse this is not an elegant and secure way to access a class member.If you want to access some common members via a base class instance, then you should declare that members in your base class (maybe as abstract or virtual), and then implement (or override) them in derived classes.
you have not defined the Farm class well. Here is example:
public class Animal { }
public class Sheep : Animal {
public void makeALamb() { }
}
public class Goat: Animal {
public void makeAGoat() { }
}
public class Farm
{
public Goat myGoat;
public Sheep mySheep;
}
public class MyFarm : Farm {
public void MyFarm() {
this.mySheep= new Animal();
this.mySheep.makeALamb();
}
}
Every animal is not goat but every goat is an animal.
Since, you want to use polymorphism, change your code to:
public abstract class Animal
{
public abstract void makeChild();
}
public class Sheep : Animal
{
public override void makeChild()
{
Console.WriteLine("A lamb is born.");
}
}
public class Cow : Animal
{
public override void makeChild()
{
Console.WriteLine("A calf is born.");
}
}
public class Farm
{
public Animal myAnimal;
}
public class SheepFarm : Farm
{
public SheepFarm()
{
this.myAnimal = new Sheep();
this.myAnimal.makeChild();
}
}
public class CowFarm : Farm
{
public CowFarm()
{
this.myAnimal = new Cow();
this.myAnimal.makeChild();
}
}
and, use the following "Main()" method:
class Program
{
static void Main(string[] args)
{
Farm sf = new SheepFarm();
Farm cf = new CowFarm();
}
}
However, I should point to you that this is not a good use case scenario. A better and simpler use case of polymorphism would be to get rid of the Farm classes and use the following "Main()" method instead of the previous one:
class Program
{
static void Main(string[] args)
{
Animal[] animals = {
new Sheep(),
new Cow(),
new Sheep(),
new Cow(),
new Cow()
};
foreach (Animal animal in animals)
{
animal.makeChild();
}
}
}

C# - using extension methods to provide default interface implementation

I'm just learning about C# extension methods, and was wondering if I can use it to provide a default implementation for an interface.
Say:
public interface Animal {
string MakeSound();
}
public static string MakeSound(this Animal) {
return "";
}
Then
public class Dog : Animal {
string MakeSound() {
return "Bark";
}
}
public class Porcupine : Animal {
}
And last:
Animal dog = new Dog();
Animal porcupine = new Porcupine();
Print(dog.MakeSound());
Print(porcupine.MakeSound());
I'd like the porcupine and any other animals that have not explicitly implemented MakeSound to use the default extension method that returns an empty string, but dog and any animal that does have an explicit implementation return its own implementation such as "Bark".
So my questions:
1. Is this doable?
2. If not, is there any other way to implement default behavior for an interface?
Abstract class instead of interface is not an option because C# doesn't support multiple inheritance and my classes are inheriting behavior of another class.
I'd generally recommend a base class, however, if that's out, you can do something like this:
public interface IAnimal { }
public interface INoisyAnimal : IAnimal {
string MakeSound();
}
public static class AnimalExtensions {
public static string MakeSound(this IAnimal someAnimal) {
if (someAnimal is INoisyAnimal) {
return (someAnimal as INoisyAnimal).MakeSound();
}
else {
return "Unknown Noise";
}
}
}
public class Dog : INoisyAnimal {
public string MakeSound() {
return "Bark";
}
}
public class Porcupine : IAnimal { }
This makes every IAnimal look like a INoisyAnimal even if it isn't really one. For example:
IAnimal dog = new Dog();
IAnimal porcupine = new Porcupine();
Console.WriteLine(dog.MakeSound()); // bark
Console.WriteLine(porcupine.MakeSound()); // Unknown Noise
However, this still isn't an actual implementation of the interface. Notice that despite appearances
Console.WriteLine(porcupine is INoisyAnimal); // false
Another option might be to create a wrapper to extend your base class when new functionality is needed:
public class NoisyAnimalWrapper : INoisyAnimal {
private readonly IAnimal animal;
public NoisyAnimalWrapper(IAnimal animal) {
this.animal = animal;
}
public string MakeSound() {
return "Unknown Noise";
}
}
public static class AnimalExtensions {
public static INoisyAnimal Noisy(this IAnimal someAnimal) {
return someAnimal as INoisyAnimal ??
new NoisyAnimalWrapper(someAnimal);
}
}
Then you can create a INoisyAnimal from any IAnimal whenever you need to:
INoisyAnimal dog = new Dog();
INoisyAnimal porcupine = new Porcupine().Noisy();
Console.WriteLine(dog.MakeSound()); // bark
Console.WriteLine(porcupine.MakeSound()); // Unknown Noise
You could also make the wrapper generic (e.g. NoisyAnimal<T> where T : IAnimal, new) and get rid of the extension method altogether. Depending on your actual use case, this may be preferable to the previous option.
I don't know exactly what is your real case or if you are just experimenting but, if only some animals are noisy, then it might a good case for Interface segregation.
For example:
public class Dog : IAnimal, INoisy
{
public string MakeSound()
{
return "Bark";
}
}
public class Porcupine : IAnimal
{
}
Then, you will only call MakeSound or objects that are actually noisy.
How about something like this? It allows you to avoid having a base class, and you can do what you had in mind, right?
public interface Animal
{
// Fields
string voice { get; }
}
public static class AnimalHelper
{
// Called for any Animal
public static string MakeSound(this Animal animal)
{
// Common code for all of them, value based on their voice
return animal.voice;
}
}
public class Dog : Animal
{
public string voice { get { return "Woof!"; } }
}
public class Purcupine : Animal
{
public string voice { get { return ""; } }
}

Categories