简体   繁体   中英

Sending base class to a method which receives derived class - c#

I have a Base class and 2 derived classes. I have a variable of base class which can hold one of the derived classes. I want to send that variable to a method which receives derived classes.

What can I do to resolve this problem without explicit cast since I don't know what the variable holds?

code:

Class A{ 
    virtual public void foo1() {/.../}
}
Class B : A{
    override public void foo1() {/.../}
}
Class C : A{
    override public void foo1() {/.../}
}
Class D{
   public foo(B argB) {/.../}
   public foo(C argC) {/.../}   

// in main
D varD = new D();
A varA = new B();   

varD.foo(varA); //--->> Problem here need explicit casting
A varC = new C();
varD.foo(varC);  //--->> Problem here need explicit casting

I don't know what derived class I'm sending to varD.foo and I want different handling of different derived classes. What can I do?

This is not what polymorphism is about - you can not pass a base class where a specialized class is expected, even when explicitly casting. Polymorphism works the other way: You can pass a specialized class wherever the base class is expected.

What you should do is make D.foo expect A and you will automatically be fine. If you add any methods to B or C which have no base implementation in A , you need to pass B anyway and can not cast an A to B or D .

Just make foo an abstract instance method of A and override the implementation in B and C . You could even keep your class D and delegate the actual work to there but it depends if this is a good idea.

Here the code with delegation to D . Also note that I omitted the method foo1() in all classes.

public abstract class A
{ 
    public abstract void foo(D d);
}

public sealed class B : A
{
    public override void foo(D d)
    {
        d.foo(this);
    }
}

public sealed class C : A
{
    public override void foo(D d)
    {
        d.foo(this);
    }
}

public sealed class D
{
   public void foo(B b) { [...] }
   public void foo(C c) { [...] }   
}

Now you can use virtual method dispatching to call the correct method.

D d = new D();

A b = new B();   
A c = new C();

b.foo(d); // Calls B.foo(D) and in turn D.foo(B).
c.foo(d); // Calls C.foo(D) and in turn D.foo(C).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM