Polymorphism and overload by static methods in C #.

I am trying to create a Factory that should return another common interface object (say Item ) according to the input parameter (I call it context) of the getItem(A context) function

Now suppose I define a new type of context: B , which inherits from A

I wanted to return another element depending on whether the object passed in Factory passed class B or A

I tried to do the following (method overload):

 class Factory { static Item getItem(A context) {...} static Item getItem(B context) {...} } 

This works fine if I do something like this:

 B bContext=new B(); Item it=Factory.getItem(bContext); 

However, if I create and create an object of type A :

 A bContext=(A) new B(); Item it=Factory.getItem(bContext); 

The first Factory method is called.

I thought that polymorphism would ensure the second method was executed even after the throw, and I would like to know if I missed something?

I know that I can continue to use one method and use the is operator to check what a variable type is, but I thought the solution presented above was a little more elegant.

+7
source share
2 answers

Congestion is determined at compile time (other than using dynamic typing in C # 4) based on the compilation time type of the arguments - and in your last fragment the compilation time type is argument A , so it calls Factory.getItem(A) .

Only calls to virtual methods are polymorphic (using overrides), where the actual runtime type of the target determines which implementation to invoke. If it makes sense for A and B to have a virtual method (overridden in B ) that Factory.getItem can Factory.getItem to handle the differences, this is great ... otherwise you are stuck with either dynamic typing or something like is .

+10
source

You cannot achieve the fact that you are pretending to have things that have been installed right now.

One option is to have some logic in your factory methods that can distinguish between the type of argument. Clunky, not really, but it works:

 class Factory { static Item getItem(ContextA context) { if (context is ContextB) {...} else {...} } } 

Another option is to make context objects responsible for creating the object. For example:

 public class ContextA { .... internal virtual Item CreateItem() { //specific creation logic for ContextA } } public class ContextB: ContextA { .... internal override Item CreateItem() { //specific creation logic for ContextB } } 

And now you can do:

 class Factory { static Item getItem(ContextA context) { return context.CreateItem(); } } 

Not if you do the following:

  ContextA context = new ContextB(); Item item = Factory.getItem(context) 

ContextB.CreateItem() will be called.

+1
source

All Articles