Farseer Farseer - 3 years ago 167
C# Question

C# polymorphous design without casting

I have Generator class that generates objects with different Interfaces with different probabilities. All objects generated by Generator is of type

BaseClass
.
BaseClass
is an abstract base class.

Lets say interfaces are
I1
,
I2


I have another class
Resolver
that has polymorphic method for two interfaces as follows:

Resolve(I1 myObj){//code for I1}


Resolve(I2 myObj){//code for I2}


The main class looks like this:

BaseClass event = Generator.generate(); //event is implements I1 or I2. Not known what interfaces until run time.
Resolver.Resolve(event); //Here i got an error, because event is BaseClass type and not I1 or I2 type.


Is there a way to solve this issue without explicitly check Interface type and cast it to appropriate interface. I came from python background, so statically typed language is new for me.

Answer Source

Consider using dependency injection to allow the event object to call the Resolver itself.

public interface IResolvable
{
    void Resolve(Resolver resolver);
}

public interface I1 : IResolvable { //... }
public interface I2 : IResolvable { //... }

public class Resolver
{
    public void Resolve(I1 i) { //... }
    public void Resolve(I2 i) { //... }
}

public abstract class BaseClass : IResolvable 
{ 
    public abstract void Resolve(Resolver resolver);
    //... 
}

An implementation would look something like:

public class Implementation1 : BaseClass, I1
{
    public override void Resolver(Resolver resolver)
    {
         resolver.Resolve(this);
    }
    //...
}

And then calling it:

Resolver resolver = new Resolver();
IResolvable evnt = Generator.Generate();
evnt.Resolve(resolver);

We can go a step further and make an interface for Resolver, so we can mock it for unit testing purposes and take full advantage of the DI pattern.

public interface IResolver
{
    void Resolve(I1 i) { //... }
    void Resolve(I2 i) { //... }
}

Then we change the definition of IResolvable

public interface IResolvable
{
    void Resolve(IResolver resolver);
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download