Overloaded method. Why is this a base class?

In the following code, I have an overloaded method that takes a parameter of type ClazzA, and another type of ClazzB. In the code shown, the first GetDescription method is called (the one that takes ClazzA as a parameter). I think I understand why. My question is: is there an elegant way to have a method that first accepts clazzB if the base object is of type classB (without having to check every object and discard it clazzB)?

public class ClazzA
{
    public virtual string Descr { get { return "A"; } }
}

public class ClazzB : ClazzA
{
    public override string Descr { get { return "B"; } }
}

public static class test
{
    public static void Main()
    {
        ClazzA test = new ClazzB();
        GetDecription(test);
    }

    public static void GetDecription(ClazzA someClazz)
    {
        Debug.WriteLine("I am here");
    }

    public static void GetDecription(ClazzB someClazz)
    {
        Debug.WriteLine("I want to be here");
    }
}

Result: "I am here"

I really want the second method to be called, since "test" is of type ClassB. Curerently the only two solutions that I have:

  • if (test ClazzB) return test GetDescription ((ClazzB));

or

  • In ClassA, doing almost the same thing ... check the type and delegate to the second method

+3
8

. ClazzA, . , , . # , ++ Java, ( virtual). , , . - . , (Accept), this (Visit). , Accept , this . - , ( . wikipedia).

:

public class ClazzA
{
   public virtual string Accept(ClassVisitor visitor)
   {
      return visitor.Visit(this);
   }
}

public class ClazzB : ClazzA
{
   public override string Accept(ClassVisitor visitor)
   {
      return visitor.Visit(this);
   }
}

public abstract class ClassVisitor
{
  public abstract string Visit(ClazzA a);
  public abstract string Visit(ClazzB b);
}

public class GetDescriptionVisitor : ClassVisitor
{
    public override string Visit(ClazzA a)
    {
       return "A";
    }

    public override string Visit(ClazzB b)
    {
       return "B";
    }
}

:

ClassVisitor visitor = new GetDescriptionVisitor();
ClazzA b = new ClazzB();
Console.WriteLine(b.Accept(visitor)); // prints "B"
+6

, , , , :

public interface IProvideDescription { 
  string GetDescription();
}

public class A : IProvideDescription {
  public string GetDescription() {
    return "I'm an A";
  }
}

public class B : IProvideDescription {
  public string GetDescription() {
    return "I'm a B";
  }
}

// to execute:

IProvideDescription x = new A();
Console.WriteLine(x.GetDescription());
x = new B();
Console.WriteLine(x.GetDescription());
+2

( "... ?" ), , test ​​ (: ). , , ClazzA. , ClazzB, , :

ClazzA test = GiveMeSomeObject();

.

+1

. , # 4, , .

dynamic instance = new ClazzB();
Console.WriteLine(GetDescription(instance));

, . , !

public interface IVisitable
{
    string Visit(DescriptionVisitor visitor);
}

public class ClazzA : IVisitable
{
    public virtual string Visit(DescriptionVisitor visitor)
    {
        return visitor.Visit(this);
    }
}

public class ClazzB : ClazzA
{
    public override string Visit(DescriptionVisitor visitor)
    {
        return visitor.Visit(this);
    }
}

public class DescriptionVisitor
{
    public string Visit(ClazzA item) { return "Description A"; }
    public string Visit(ClazzB item) { return "Description B"; }
}

DescriptionVisitor, ClazzB.

var visitor = new DescriptionVisitor();
ClazzA a = new ClazzB();
Console.WriteLine(a.Visit(visitor));
+1

, . , GetDescription ClassA , ClassB - .

+1

@roken, B, Descr . , , ClazzB . - , - , dynamic :

GetDecription((dynamic)test);

, , GetDescription(test). GetDecription(ClazzA):

if (someClazz is ClazzB)
{
    GetDescription((ClazzB)someClazz);
    return;
}
0

You can get the behavior you want using the "dynamic" keyword that was introduced in .Net 4.0. It evaluates the type at runtime and selects the correct overload.

public static class test
{
    public static void Main()
    {
        dynamic test = new ClazzB();
        GetDecription(test);
    }

    public static void GetDecription(ClazzA someClazz)
    {
        Debug.WriteLine("I am here");
    }

    public static void GetDecription(ClazzB someClazz)
    {
        Debug.WriteLine("I want to be here");
    }
}
0
source

You can use only one method GetDescription():

public String GetDescription(ClassA in) {
    if (in is ClassB) {
        return (in as ClassB).Descr 
    }

    return in.Descr;
}
-2
source

All Articles