As far as I know, polymorphism is related to class inheritance. Something like this:
class NormalCardStatus : ICardStatus {
void DoStuff(Card card) {
// ...
}
}
class UnderwaterCardStatus : ICardStatus {
void DoStuff(Card card) {
// ...
}
}
In a C# refactoring book by Martin Fowler on page 35 it is suggested to replace Conditional Logic of another class with Polymorphism. However, in the suggested solution I do not see any inheritance. What kind of polymorphism is that?
polymorphism is related to class inheritance
That is true. A lot of things in OOP are related to class inheritance though, so knowing the above may not really help much.
I'm not familiar with the book you're using, but I think it's not hard to explain the concept of replacing conditional logic with polymorphism.
Consider this example object:
class Animal
{
public string Name { get; private set; }
public Animal(string name)
{
Name = name;
}
public void MakeSound()
{
switch (Name)
{
case "Dog":
Bark();
break;
case "Cat":
Meow();
break;
}
}
private void Bark() { /* bark implementation goes here */ }
private void Meow() { /* meow implementation goes here */ }
}
Used like this:
Animal animal1 = new Animal("Dog"), animal2 = new Animal("Cat");
animal1.MakeSound(); // barks!
animal2.MakeSound(); // meows!
Note in the above, every time you call MakeSound(), the class has a condition. It checks the value of Name, and calls a different method depending on that value.
Polymorphism allows you to declare the basic behavior in a base class, but then delegate the implementation of that behavior in derived classes:
abstract class Animal
{
public string Name { get; private set; }
protected Animal(string name)
{
Name = name;
}
public abstract void MakeSound();
}
class Dog : Animal
{
public Dog() : base("Dog") { }
public override void MakeSound() { Bark(); }
private void Bark() { /* bark implementation goes here */ }
}
class Cat : Animal
{
public Cat() : base("Cat") { }
public override void MakeSound() { Meow(); }
private void Meow() { /* meow implementation goes here */ }
}
Used like this:
Animal animal1 = new Dog(), animal2 = new Cat();
animal1.MakeSound(); // barks!
animal2.MakeSound(); // meows!
Note that here, we decide when the object is created what kind of object it is, same as before, but this is expressed as the type of the object now, instead of just a string that is passed to the constructor.
Then we can still operate with the object as Animal, and still receive different behaviors depending on which object kind we originally created, but the behavior is automatically directed to the appropriate implementation based on the object type, rather than a runtime comparison on some property value.
Of course, now that I type all the above, it occurs to me that there may already be a similar discussion on Stack Overflow explaining all of this. If someone else wants to try to look that up, I don't mind. But in the meantime, I hope the above helps.
Related
// Cannot change source code
class Base
{
public virtual void Say()
{
Console.WriteLine("Called from Base.");
}
}
// Cannot change source code
class Derived : Base
{
public override void Say()
{
Console.WriteLine("Called from Derived.");
base.Say();
}
}
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
}
class Program
{
static void Main(string[] args)
{
SpecialDerived sd = new SpecialDerived();
sd.Say();
}
}
The result is:
Called from Special Derived.
Called from Derived. /* this is not expected */
Called from Base.
How can I rewrite SpecialDerived class so that middle class "Derived"'s method is not called?
UPDATE:
The reason why I want to inherit from Derived instead of Base is Derived class contains a lot of other implementations. Since I can't do base.base.method() here, I guess the best way is to do the following?
// Cannot change source code
class Derived : Base
{
public override void Say()
{
CustomSay();
base.Say();
}
protected virtual void CustomSay()
{
Console.WriteLine("Called from Derived.");
}
}
class SpecialDerived : Derived
{
/*
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
*/
protected override void CustomSay()
{
Console.WriteLine("Called from Special Derived.");
}
}
Just want to add this here, since people still return to this question even after many time. Of course it's bad practice, but it's still possible (in principle) to do what author wants with:
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
var ptr = typeof(Base).GetMethod("Say").MethodHandle.GetFunctionPointer();
var baseSay = (Action)Activator.CreateInstance(typeof(Action), this, ptr);
baseSay();
}
}
This is a bad programming practice, and not allowed in C#. It's a bad programming practice because
The details of the grandbase are implementation details of the base; you shouldn't be relying on them. The base class is providing an abstraction overtop of the grandbase; you should be using that abstraction, not building a bypass to avoid it.
To illustrate a specific example of the previous point: if allowed, this pattern would be yet another way of making code susceptible to brittle-base-class failures. Suppose C derives from B which derives from A. Code in C uses base.base to call a method of A. Then the author of B realizes that they have put too much gear in class B, and a better approach is to make intermediate class B2 that derives from A, and B derives from B2. After that change, code in C is calling a method in B2, not in A, because C's author made an assumption that the implementation details of B, namely, that its direct base class is A, would never change. Many design decisions in C# are to mitigate the likelihood of various kinds of brittle base failures; the decision to make base.base illegal entirely prevents this particular flavour of that failure pattern.
You derived from your base because you like what it does and want to reuse and extend it. If you don't like what it does and want to work around it rather than work with it, then why did you derive from it in the first place? Derive from the grandbase yourself if that's the functionality you want to use and extend.
The base might require certain invariants for security or semantic consistency purposes that are maintained by the details of how the base uses the methods of the grandbase. Allowing a derived class of the base to skip the code that maintains those invariants could put the base into an inconsistent, corrupted state.
You can't from C#. From IL, this is actually supported. You can do a non-virt call to any of your parent classes... but please don't. :)
The answer (which I know is not what you're looking for) is:
class SpecialDerived : Base
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.Say();
}
}
The truth is, you only have direct interaction with the class you inherit from. Think of that class as a layer - providing as much or as little of it or its parent's functionality as it desires to its derived classes.
EDIT:
Your edit works, but I think I would use something like this:
class Derived : Base
{
protected bool _useBaseSay = false;
public override void Say()
{
if(this._useBaseSay)
base.Say();
else
Console.WriteLine("Called from Derived");
}
}
Of course, in a real implementation, you might do something more like this for extensibility and maintainability:
class Derived : Base
{
protected enum Mode
{
Standard,
BaseFunctionality,
Verbose
//etc
}
protected Mode Mode
{
get; set;
}
public override void Say()
{
if(this.Mode == Mode.BaseFunctionality)
base.Say();
else
Console.WriteLine("Called from Derived");
}
}
Then, derived classes can control their parents' state appropriately.
Why not simply cast the child class to a specific parent class and invoke the specific implementation then? This is a special case situation and a special case solution should be used. You will have to use the new keyword in the children methods though.
public class SuperBase
{
public string Speak() { return "Blah in SuperBase"; }
}
public class Base : SuperBase
{
public new string Speak() { return "Blah in Base"; }
}
public class Child : Base
{
public new string Speak() { return "Blah in Child"; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Child childObj = new Child();
Console.WriteLine(childObj.Speak());
// casting the child to parent first and then calling Speak()
Console.WriteLine((childObj as Base).Speak());
Console.WriteLine((childObj as SuperBase).Speak());
}
}
public class A
{
public int i = 0;
internal virtual void test()
{
Console.WriteLine("A test");
}
}
public class B : A
{
public new int i = 1;
public new void test()
{
Console.WriteLine("B test");
}
}
public class C : B
{
public new int i = 2;
public new void test()
{
Console.WriteLine("C test - ");
(this as A).test();
}
}
You can also make a simple function in first level derived class, to call grand base function
My 2c for this is to implement the functionality you require to be called in a toolkit class and call that from wherever you need:
// Util.cs
static class Util
{
static void DoSomething( FooBase foo ) {}
}
// FooBase.cs
class FooBase
{
virtual void Do() { Util.DoSomething( this ); }
}
// FooDerived.cs
class FooDerived : FooBase
{
override void Do() { ... }
}
// FooDerived2.cs
class FooDerived2 : FooDerived
{
override void Do() { Util.DoSomething( this ); }
}
This does require some thought as to access privilege, you may need to add some internal accessor methods to facilitate the functionality.
In cases where you do not have access to the derived class source, but need all the source of the derived class besides the current method, then I would recommended you should also do a derived class and call the implementation of the derived class.
Here is an example:
//No access to the source of the following classes
public class Base
{
public virtual void method1(){ Console.WriteLine("In Base");}
}
public class Derived : Base
{
public override void method1(){ Console.WriteLine("In Derived");}
public void method2(){ Console.WriteLine("Some important method in Derived");}
}
//Here should go your classes
//First do your own derived class
public class MyDerived : Base
{
}
//Then derive from the derived class
//and call the bass class implementation via your derived class
public class specialDerived : Derived
{
public override void method1()
{
MyDerived md = new MyDerived();
//This is actually the base.base class implementation
MyDerived.method1();
}
}
As can be seen from previous posts, one can argue that if class functionality needs to be circumvented then something is wrong in the class architecture. That might be true, but one cannot always restructure or refactor the class structure on a large mature project. The various levels of change management might be one problem, but to keep existing functionality operating the same after refactoring is not always a trivial task, especially if time constraints apply. On a mature project it can be quite an undertaking to keep various regression tests from passing after a code restructure; there are often obscure "oddities" that show up.
We had a similar problem in some cases inherited functionality should not execute (or should perform something else). The approach we followed below, was to put the base code that need to be excluded in a separate virtual function. This function can then be overridden in the derived class and the functionality excluded or altered. In this example "Text 2" can be prevented from output in the derived class.
public class Base
{
public virtual void Foo()
{
Console.WriteLine("Hello from Base");
}
}
public class Derived : Base
{
public override void Foo()
{
base.Foo();
Console.WriteLine("Text 1");
WriteText2Func();
Console.WriteLine("Text 3");
}
protected virtual void WriteText2Func()
{
Console.WriteLine("Text 2");
}
}
public class Special : Derived
{
public override void WriteText2Func()
{
//WriteText2Func will write nothing when
//method Foo is called from class Special.
//Also it can be modified to do something else.
}
}
There seems to be a lot of these questions surrounding inheriting a member method from a Grandparent Class, overriding it in a second Class, then calling its method again from a Grandchild Class. Why not just inherit the grandparent's members down to the grandchildren?
class A
{
private string mystring = "A";
public string Method1()
{
return mystring;
}
}
class B : A
{
// this inherits Method1() naturally
}
class C : B
{
// this inherits Method1() naturally
}
string newstring = "";
A a = new A();
B b = new B();
C c = new C();
newstring = a.Method1();// returns "A"
newstring = b.Method1();// returns "A"
newstring = c.Method1();// returns "A"
Seems simple....the grandchild inherits the grandparents method here. Think about it.....that's how "Object" and its members like ToString() are inherited down to all classes in C#. I'm thinking Microsoft has not done a good job of explaining basic inheritance. There is too much focus on polymorphism and implementation. When I dig through their documentation there are no examples of this very basic idea. :(
I had the same problem as the OP, where I only wanted to override a single method in the middle Class, leaving all other methods alone. My scenario was:
Class A - base class, DB access, uneditable.
Class B : A - "record type" specific functionality (editable, but only if backward compatible).
Class C : B - one particular field for one particular client.
I did very similar to the second part of the OP posting, except I put the base call into it's own method, which I called from from Say() method.
class Derived : Base
{
public override void Say()
{
Console.WriteLine("Called from Derived.");
BaseSay();
}
protected virtual void BaseSay()
{
base.Say();
}
}
class SpecialDerived : Derived
{
public override void Say()
{
Console.WriteLine("Called from Special Derived.");
base.BaseSay();
}
}
You could repeat this ad infinitum, giving, for example SpecialDerived a BaseBaseSay() method if you needed an ExtraSpecialDerived override to the SpecialDerived.
The best part of this is that if the Derived changes its inheritance from Base to Base2, all other overrides follow suit without needing changes.
If you want to access to base class data you must use "this" keyword or you use this keyword as reference for class.
namespace thiskeyword
{
class Program
{
static void Main(string[] args)
{
I i = new I();
int res = i.m1();
Console.WriteLine(res);
Console.ReadLine();
}
}
public class E
{
new public int x = 3;
}
public class F:E
{
new public int x = 5;
}
public class G:F
{
new public int x = 50;
}
public class H:G
{
new public int x = 20;
}
public class I:H
{
new public int x = 30;
public int m1()
{
// (this as <classname >) will use for accessing data to base class
int z = (this as I).x + base.x + (this as G).x + (this as F).x + (this as E).x; // base.x refer to H
return z;
}
}
}
I want to avoid using casting base class type to derived class type I can do this successfully If I want to access generic functionality but if I want specialised functionality I cant access this without casting
I have written code to demonstrate what I've already tried.
public abstract class Animal : IAnimal
{
public void Move()
{
}
}
public interface IAnimal
{
void Move();
}
public interface IDog:IAnimal
{
void bark();
}
public class Dog : IDog
{
public void Move()
{
}
public void bark()
{
}
}
static void Main(string[] args)
{
Animal animal = null;
IDog dog = animal as IDog;
dog.bark(); // can access specialized method
IAnimal puppy = new Dog();
puppy.Move(); // can only access generic functions
}
How can I re-design classes to access "bark" method without casting?
Short answer: You cannot and you shouldn't be able.
What you could do instead, is probably implement a MakeNoise() method in IAnimal interface because you'd expect animals in general to make noises.
However, if you insist on keeping Bark() on IDog, you wouldn't expect an IDuck to be able to access it - it should have a Quack() method. Neither will be available from objects downcasted to IAnimal because how can you guess whether it's a Duck or a Dog?
I'll post bit more "real life" example of why you might need inheritance in programming, because example you've provided is sort-of "book example" and thus it is obscure and vague as well.
using System.Collections.Generic;
namespace ConsoleApp1
{
public static class DocumentHandling
{
public static List<IAccountable> Documents;
public static dynamic InternalService { get; set; }
public static dynamic IRS { get; set; }
public static void HandleDocuments()
{
foreach (var document in Documents)
{
document.Account();
}
}
}
public interface IAccountable
{
void Account();
}
public abstract class Document
{
public int DatabaseId { get; set; }
public string Title { get; set; }
}
public abstract class DocumentWithPositions : Document
{
public int[] PositionsIds { get; set; }
}
public class Invoice : DocumentWithPositions, IAccountable
{
public void Account()
{
var positions = DocumentHandling.InternalService.PreparePositions(this.PositionsIds);
DocumentHandling.IRS.RegisterInvoice(positions);
}
}
public class Receipt : DocumentWithPositions, IAccountable
{
public void Account()
{
Invoice invoice = DocumentHandling.InternalService.ConvertToReceipt(this);
invoice.Account();
}
}
}
See how I can stuff both Invoice and Receipt documents in single List (because they're downcasted to IAccountable)? Now I can account them all at once, even though their concrete implementations handle accounting process differently.
Let's takle the Liskov Substitution Principle first and then talk about OOP and inheritance.
First, lets talk about Abstract Data Types. In her paper she uses the concept of objects from types.
An Abstact Data Type (ADT) is a description of a type with all it's operations and behaviors. All clients of an ADT should know what to expect when using it.
Here's an example:
Let's define a Stack as an ADT
Operations: push, pop, topElement, size, isEmpty
Behaviors:
push : always adds an element to the top of the stack!
size : return the number of elements in the stack
pop : removes and element from the top of the stack. error if the stack is empty
topElement : return the top element in the stack. error if the stack is empty
isEmpty : return true is the stack is empty, false otherwise
At this point we desribed what is a Stack in terms of it's operations and how it should behave. We are not talking about clases here nor concrete implementations. This makes is an Abstract Data Type.
Now lets make a type hierarchy. In C# both interfaces and classes are types. They are different as interfaces define only operations, so in a sense they are a contract. They define the operations of an ADT. Usually people do assume that only classes that inherit from one another define a type hierarchy. It's true that classes that inherit from one another are called Superclass or Baseclass and a Subclass, but from the point of view of Types we do have Supertype and Subtype for both interfaces and classes as they both define types.
NOTE: For simplicity i'll skip error checking in the implementations of the methods
// interfaces are types. they define a contract so we can say that
// they define the operations of an ADT
public interface IStack<T> {
T Top();
int Size();
void Push(T element);
void Pop();
bool IsEmpty();
}
// the correct term here for C# whould be 'implements interface' but from
// point of view of ADTs and *Types* ListBasedStack is a *Subtype*
public class ListBasedStack<T> : IStack<T> {
private List<T> mElements;
public int Size() { return mElements.Count; }
public T Top() { mElements(mElements.Count - 1); }
public void Push(T element) { mElements.Add(element); }
public void Pop() { mElements.Remove(mElements.Count - 1); }
public bool IsEmpty() { return mElements.Count > 0; }
}
public class SetBasedStack<T> : IStack<T> {
private Set<T> mElements;
public int Size() { return mElements.Count; }
public T Top() { mElements.Last(); }
public void Push(T element) { mElements.Add(element); }
public void Pop() { mElements.RemoveLast(); }
public bool IsEmpty() { return mElements.Count > 0; }
}
Notice that we have two Subtypes of the same ADT. Now lets consider a test case.
public class Tests {
public void TestListBasedStackPush() {
EnsureUniqueElementsArePushesToAStack(new ListBasedStack<int>());
}
public void TestSetBasedStackPush() {
EnsureUniqueElementsArePushesToAStack(new SetBasedStack<int>());
}
public void EnsureUniqueElementsArePushesToAStack(IStack<int> stack) {
stack.Push(1);
stack.Push(1);
Assert.IsTrue(stack.Size() == 2);
}
}
And the results are:
TestListBasedStackPush: Pass
TestSetBasedStackPush: FAIL!
SetBasedStack violates the rules for push: always adds an element to the top of the stack! as a set can contain only unique elements and the second stack.Push(1) wont add new element to the stack.
This is a violation of LSP.
Now about examples and type hierarchies like IAnimal and Dog. When you are in the right abstaction level a type should behave like it's suposed to. If you do need a Dog, use a Dog. If you do need an IAnimal, use IAnimal.
How do you access Bark if you have IAnimal? You DON'T!!. You are at the wrong level of abstraction. If you do need a Dog, use a Dog. Cast if you have to.
public class Veterenerian {
public void ClipDogNails(IAnimal animal) { } // NO!
public void ClipDogNails(Dog dog) { } // YES!
}
private Veterenerian mOnDutyVeterenerian;
private List<IAnimal> mAnimals;
public ClipAllDogsNails() {
// Yes
foreach(var dog in mAnimals.OffType<Dog>()) {
mOnDutyVeterenerian.ClipDogNails(dog);
}
// NO
foreach(var animal in mAnimals) {
mOnDutyVeterenerian.ClipDogNails(animal);
}
}
Do you need to cast? Sometimes yes. If it better to not do it? Yes, most of the time.
How do you solve the above problem? You can make the Dog clip it's own nails. Are you doing to add method ClipNails to IAnimal and make only animals with nails implement this and leave other animal subclasses leave this method empty? NO! Because it doesn't make sense in the level of abstraction of IAnimal and it also violates LSP. Also if you do this you can call animal.ClipNails() and this will be fine, but if you do have a schedule that says that dogs should clip nails on Friday other animals Monday your stuck again as you can make all animals clip their nails, not only dogs.
Sometimes an object of one Type is to be used by objects from another Type. Some operations doesn't make sense in a type. This example illustates how a Dog cannot clip it's nails. It should be done by a Veterenerial.
Yet we do need to work on the IAnimal level of abstraction. All things in a Veterenerian Clinic are animals. But sometimes some operations need to be performed on specific type of animal, a Dog in this case, so we do need to filter the animals by their Type.
But that's a completely different problem from the above example with Stack.
Here's an example on when casting should not be used and the client code should not case about the concrete implementation:
public abstract class Serializer {
public abstract byte[] Serialize(object o);
}
public class JSONSerializer : Serializer {
public override byte[] Serialize(object o) { ... }
}
public class BinarySerializer : Serializer {
public override byte[] Serialize(object o) { ... }
}
public void DoSomeSerialization(Serializer serializer, Event e) {
EventStore.Store(serializer.Serialize(e));
}
DoSomeSerialization method should not care about the serializer that is passed to it. You can pass any Serializer that adheres to the Serializer spec, it should work. That's the point of having an abstraction with multiple implemenations. DoSomeSerialization works on the level of Serializer. We can define the Serializer as an ADT. All classes that are derive from Serializer should adhere to the specification of the ADT and the system works just fine. No casting here, no need to do casting here as the problem is different.
Let there be class NaturalFood and two classes inherit from this class; class Fruits and class Vegetables
abstract class NaturalFood
{
enum AllList
{
//empty list as a placeholder
}
protected string Name;
}
class Fruits : NaturalFood
{
enum AllList
{
Apple = 1,
Banana = 2
}
}
class Vegetables : NaturalFood
{
enum AllList
{
Carrot = 1,
Potatoes = 2
}
}
I want to enforce that any class derived from class NaturalFood must declare and/or override the AllList enumeration. Effectively the enumeration will contain list specific to the derived class. How do I do this ?
Edit: My basic requirement is that each class deriving from a base class must have its own list of "something" that is specific to it. Enumeration is just a way of creating a list. I hope you get the gist from my example. I want to take advantage of what Enumeration offers viz. intellisense, toString() etc.
Edit2: Isn't my example very practical enough ? If I put the entire enumeration in the base class (NaturalFood), how do I know which of the enumerated values are specific to which derived class ? Let us say each derived class is "publishing something" it has to offer in form of enumerated constants and I want to enforce this constraint on every derived class. So in other words, my question is how to enforce a constraint on derived class like in scenario described here ?
Actually, there's no sense to override these values. Actually, the advantages of override is that you can call a method of a derived class without knowing the derived class itself.
For example :
static void Main()
{
NaturalFood food = GetSomeFood(); // At this point, we don't know the actual type
food.SomeMethodInBaseClass(); // ok
}
static NaturalFood GetSomeFood()
{
if(somecondition) {
return new Fruits();
}
else{
return new Vegetables();
}
}
public abstract class NaturalFood
{
public abstract void SomeMethodInBaseClass();
}
public class Fruits : NaturalFood
{
public override void SomeMethodInBaseClass(){
Console.WriteLine("I'm a fruit");
}
}
public class Vegetables : NaturalFood
{
public override void SomeMethodInBaseClass(){
Console.WriteLine("I'm a vegetable");
}
}
No imagine what you wanted to do. In the main method, try to call the AllList :
static void Main()
{
NaturalFood food = GetSomeFood(); // At this point, we don't know the actual type
food.SomeMethodInBaseClass(); // ok
food.AllList.XXXX; // What? it won't compile
}
This won't compile. The compiler has no way to know the actual derived class to infer the available enumeration values.
However, if you remove the enumeration from the base type, this will works :
static void Main()
{
NaturalFood food = GetSomeFood(); // At this point, we don't know the actual type
food.SomeMethodInBaseClass(); // ok
Fruits f = new Fruits();
Console.WriteLine( f.AllList.Apple); // Ok
Vegetable v = new Vegetable ();
Console.WriteLine( v.AllList.Potatoe); // Ok
}
But as you can see, you have to know explicitly the actual type, and thus, make the polymorphic useless.
[Edit] It's hard to answer to your second edit. Actually there are many many ways to validate such constraint. Without more context it may be difficult to answer. The most simple way I think, is to add to each derived class a overriden property that describe what kind of enumeration is accepted.
public enum NaturalFoodType {
Unknown = 0,
Apple= 1,
Banana = 2,
Potatoe = 3,
Cucumber = 4
}
public abstract class NaturalFood
{
public abstract void SomeMethodInBaseClass();
public abstract IEnumerable<NaturalFoodType> AcceptedFoodType { get; }
public bool IsValid(NaturalFoodType type){
return AcceptedFootType.Contains(type);
}
}
public class Fruits : NaturalFood
{
public override void SomeMethodInBaseClass(){
Console.WriteLine("I'm a fruit");
}
public override NaturalFoodType {
get {
yield return NaturalFoodType.Apple;
yield return NaturalFoodType.Banana;
}
}
}
public class Vegetables : NaturalFood
{
public override void SomeMethodInBaseClass(){
Console.WriteLine("I'm a vegetable");
}
public override NaturalFoodType {
get {
yield return NaturalFoodType.Potatoe;
yield return NaturalFoodType.Cucumber;
}
}
}
But honestly, it start to add a lot of plumbing code, that become quite unreadable. You should consider the problem at a higher scope to find an acceptable solution.
This is not possible because enums are types, not class members... and the fact they are declared inside a class doesn't make them members of that class, they are just nested. Every class can and has to define it's own private enum AllList type... so your actual code is the only possible way to go.
If you want to obtain something like this and you have only few values to deal with, stick with properties overrides:
class A
{
public virtual String Value
{
get
{
return "A";
}
}
}
class B : A
{
public override String Value
{
get
{
return "B";
}
}
}
I have the following concrete Animal products: Dog and Cat.
I am using a parameterized Factory method to create said products. Depending on the AnimalInfo parameter that is passed to the Factory method, a concrete product will be created. The mapping logic is placed in the Factory method.
Here is my code:
public abstract class AnimalInfo
{
public abstract String Sound { get; }
}
public class DogInfo : AnimalInfo
{
public override string Sound
{
get { return "Bark"; }
}
}
public class CatInfo : AnimalInfo
{
public override string Sound
{
get { return "Meow"; }
}
}
public abstract class Animal
{
public abstract void Talk();
}
public class Dog : Animal
{
private readonly DogInfo _info;
public Dog(DogInfo aInfo)
{
_info = aInfo;
}
public override void Talk()
{
Console.WriteLine(_info.Sound);
}
}
public class Cat : Animal
{
private readonly CatInfo _info;
public Cat(CatInfo aInfo)
{
_info = aInfo;
}
public override void Talk()
{
Console.WriteLine(_info.Sound);
}
}
Here's my Factory method with its logic:
public static class AnimalFactory
{
public static Animal CreateAnimal(AnimalInfo aInfo)
{
if (aInfo is DogInfo)
return new Dog(aInfo as DogInfo);
if (aInfo is CatInfo)
return new Cat(aInfo as CatInfo);
return null;
}
}
The problem I'm seeing here is that the Factory method itself violates the Open/Closed principle in such a way that if I add a new Animal, I will need to modify the Factory method to reflect the new mapping.
Is there a way to make the creation more "dynamic" via reflection? More importantly, is there any anti-pattern in my design?
Let me sidestep a bit. The SOLID principles are good. But realize at some point, the principles break down, a fact even the originator of the SOLID term acknowledges. Yes, you want to follow single responsibility, open/closed, etc., but when you do so, something has to know how to create all those things that are otherwise nicely decoupled with single responsibilities.
Think about one of the things Uncle Bob said regarding ifs and switches in your code. "Have it exactly once." It stands to reason that the long if or the switch will indeed be a violation of SRP and OCP. And that's OK, if you have that violation once.
So go ahead, have your
if (a)
return x;
else if (b)
return y;
else if (c)
return z;
else
throw new InvalidOperationException();
And have it once. Yes, it's a violation of OCP. Yes, it might violate SRP. But something somewhere has to. The key is reducing the number of those somethings and those somewheres.
The easy way out is to make AnimalInfo itself the factory:
public abstract class AnimalInfo<T> where T: Animal
{
public abstract String Sound { get; }
public abstract T CreateAnimal();
}
Implementation for DogInfo:
public class DogInfo : AnimalInfo<Dog>
{
public override string Sound
{
get { return "Bark"; }
}
public override Dog CreateAnimal()
{
return new Dog(this);
}
}
You could keep your current static Factory if you wanted to:
public static class AnimalFactory
{
public static Animal CreateAnimal(AnimalInfo aInfo)
{
return aInfo.CreateAnimal();
}
}
Not exactly strict adherance to the Factory pattern, IMO, but no longer violates your open/close principle.
If you are looking for a reflection based method, you could do something like the following...
public static class AnimalFactory
{
public static Animal CreateAnimal(Type animalType)
{
return Activator.CreateInstance(animalType) as Animal;
}
public static Animal CreateAnimal(string animalType)
{
Type type = Assembly.GetExecutingAssembly().GetType(animalType);
return Activator.CreateInstance(type) as Animal;
}
}
How do you declare a method in C# that should be overridden (or overridable) by a dereived class - possibly even outside your assembly - but that should be callable only from within the actual class?
(i.e. like a private virtual function in C++)
[edit]
private virtual is exactly what I intend: "Here's a way to modify my behavior, but you are still not allowed to call this function directly (because calling it requires arcane invocations that only my base class shall do)"
So to clarify it: what is the best expression for that in C#?
When you say it should only be callable "within the actual class" do you mean the base class or the derived class? Neither of these is feasible on its own. The closest is to use a protected method, which means it can be called from the declaring class, the derived class, and any further-derived class.
C# makes a stronger guarantee for "private" than C++ does. In C++, you can indeed override a private virtual method. But that means that code in a base class can execute code in a derived class. Breaking the promise that the private method is truly private and can only be called by methods in the same class.
Something that doesn't help here is that C++ doesn't require repeating the virtual keyword. Leading up to hard to reverse-engineer mysteries like this one:
#include "stdafx.h"
#include <iostream>
class Base {
private:
virtual void Method() = 0;
public:
void Test() {
Method();
}
};
class Derived : public Base {
private:
void Method() { std::cout << "Who the heck called me?"; }
};
int _tmain(int argc, _TCHAR* argv[])
{
Base* p = new Derived;
p->Test();
}
I agree there's a possible role for private inheritance. The C# language designers said No! though.
A private member is not visible to child classes. I think protected virtual will perform the way you'd like?
UPDATE:
Here in greater detail is an explaination of what you can do with inheritance and overriding functions within C#. I tried to use a somewhat meaningful example, but consider it understood that its a poor class design and I wouldn't ever recommend implementing the classes described in this way. However, I hope perhaps this will give you an avenue to approach solving your original problem in a manner that might be acceptable. There is no way to prevent a concrete class from calling any of its members, but if your structure is like this in anyway, perhaps its not issue.
public abstract class Animal
{
public void DisplayAttributes()
{
Console.WriteLine(Header());
Console.WriteLine("Name: " + Name());
Console.WriteLine("Legs: " + Legs());
Console.WriteLine();
}
protected virtual int Legs()
{
return 4;
}
private string Header()
{
return "Displaying Animal Attributes";
}
protected abstract string Name();
}
public class Bird : Animal
{
protected override string Name()
{
return "Bird";
}
protected override int Legs()
{
return 2;
}
}
public class Zebra : Animal
{
protected override string Name()
{
return "Zebra";
}
}
public class Fish : Animal
{
protected override string Name()
{
return "Fish";
}
protected override int Legs()
{
return 0;
}
private string Header()
{
return "Displaying Fish Attributes";
}
protected virtual int Gils()
{
return 2;
}
public new void DisplayAttributes()
{
Console.WriteLine(Header());
Console.WriteLine("Name: " + Name());
Console.WriteLine("Gils: " + Gils());
Console.WriteLine();
}
}
class Program
{
static void Main(string[] args)
{
Bird bird = new Bird();
bird.DisplayAttributes();
//Displaying Animal Attributes
//Name: Bird
//Legs: 2
Zebra zebra = new Zebra();
zebra.DisplayAttributes();
//Displaying Animal Attributes
//Name: Zebra
//Legs: 4
Fish fish = new Fish();
fish.DisplayAttributes();
//Displaying Fish Attributes
//Name: Fish
//Gils: 2
List<Animal> animalCollection = new List<Animal>();
animalCollection.Add(bird);
animalCollection.Add(zebra);
animalCollection.Add(fish);
foreach (Animal animal in animalCollection)
{
animal.DisplayAttributes();
//Displaying Animal Attributes
//Name: Bird
//Legs: 2
//Displaying Animal Attributes
//Name: Zebra
//Legs: 4
//Displaying Animal Attributes
//Name: Fish
//Legs: 0
//*Note the difference here
//Inheritted member cannot override the
//base class functionality of a non-virtual member
}
}
}
In this example, Bird, Zebra, and Fish could all call their Name and Legs methods, but within the context if this example, there wouldn't necessarily be utility in doing so. Additionally, as shown by Fish, the DisplayAttributes() can be modified for an instance of a concrete derived class; but when you're looking at an Animal, as in the foreach loop, you get the base classes DisplayAttributes behavior, regardless of the actual type of animal. I hope this may help povide the type of functionality you would like to replicate.
Here's an example of what vboctor has already mentioned:
public class Base
{
private Func<Base, int> func;
protected void SetFunc(Func<Base, int> func)
{
this.func = func;
}
private void CallFunc()
{
if (func != null)
{
var i = func(this);
}
}
}
public class Sub : Base
{
private void DoFuncyStuff()
{
this.SetFunc(b => 42);
}
}
Did you consider the use of a delegate to do that? You can allow the derived class to set the delegate via some protected property or passing it to your constructor. You can also default the delegate to your internal implementation which is a private method on your base class.
Why do you need it to be private? Protected should be sufficient, here. You're asking the subclass author to write code that they can't call. What does this accomplish? They could use that code anyway.
As I read your question, you could mean two things.
First ,if if you want a function in Class A that can be overriden in Child Class B but is not visible to any outside class:
public class ClassA
{
protected virtual ReturnType FunctionName(...) { ... }
}
public class ClassB
{
protected override ReturnType FunctionName(...) { ... }
}
Second, if you want to force an implementing class to define the function:
public abstract class ClassA
{
protected abstract ReturnType FunctionName(...);
}
public class ClassB
{
protected override ReturnType FunctionName(...) { ... }
}
Another concept you might look at if you are just digging into C# that is kinda related is partial classes. This is the idea of two source files being combined at compile time to create one class, both from the same assembly:
File 1:
public partial class ClassA
{
private ReturnType FunctionName(...);
}
File 2:
public partial class ClassA
{
//actual implimentation
private ReturnType FunctionName(...){ ... };
}
Partials are not widely used except when dealing with designed-generated files, like the Linq2Sql files, or EDM, or WinForms, etc.
Guess this will not work out as you intended, but let me sketch some pseudo-code for you:
public interface BaseClassFunction {
void PleaseCallMe();
}
public class BaseClass {
private BaseClassFunction fn;
public BaseClass(BaseClassFunction fn) {
this.fn = fn;
}
private CallMe() {
fn.PleaseCallMe();
}
public PublicCallMe() {
CallMe();
}
}
private class DerivedClassFunction : BaseClassFunction {
void PleaseCallMe() { ... do something important ... }
}
public class DerivedClassFunction {
public DerivedClassFunction() : BaseClass(new DerivedClassFunction()) {
}
}