-1

I have a base class in C# like:

public class A{
  public A something() {
     //...
  }
}

And a derived class like:

public class B:A

When I do:

B obj = new B();
obj = obj.something();

VS throws an error saying (something like) "A can't be converted to B". Isn't it supposed to return B and not A?

Update: Thank you all.

I've changed A.something(string) and now is A.something(int). The values passed to it are always ints, so... B (and other "sister" classes) are just a midstep in a full refactoring of the code, so they will disappear.

The case is that I have 4 classes that do the same and I'm changing'em for a unified one. Thus the need to return "B" objects for now.

  • 2
    because your function something() return type is `A` and you can not hold your parent members in child but otherway(Parent reference variable can point to child class instance) is possible. – Sudhakar Tillapudi Mar 10 '14 at 13:38
  • It seems like you are trying to implement the factory method pattern, check this out: http://www.dofactory.com/Patterns/PatternFactory.aspx – Jportelas Mar 10 '14 at 13:48

4 Answers4

0

VS throws an error saying (something like) "A can't be converted to B". Isn't it supposed to return B and not A?

because your parent class function something() return type is A, and you are trying save that in Child class reference variable obj as below:

obj = obj.something(); //something returns instance of `A`

here child class reference variable obj can not point to parent class instance but otherway(Parent class reference variable can point to child class instance) is possible.

Sudhakar Tillapudi
  • 25,935
  • 5
  • 37
  • 67
0

you should consider changing the return type of the something() method in A class.

  • it should return void

  • you can pass a parameter via reference if you need to modify it in the function

This way you can overload/override the method in the derived class to get a different behavior if you need to.

the way it looks now there is not much you can do except a reinterpret_cast which will cause problems later on.

Pandrei
  • 4,843
  • 3
  • 27
  • 44
-1

No, even though it's defined in the base class, the return type won't be different, it will still return an instance of A which is not necessarily convertible to B. You could do something like this:

public class A{
  public virtual A something() {
     //...
  }
}

public class B:A
{
   public override A something() {
     return new B();
   }
}

B obj = new B();
obj = obj.something() as B;

Of course, the override does not really solve anything here. You could just return a B in the base class and it would work the same way, but that's just awkward. I think your issue is that you are not following the LISKOV substitution principle here: you should be able to replace every instance of A with an instance that implements A without affecting the client. Downcasting in general is a code smell. You should treat all instances as A's and vary the behavior in your subclasses, not in the clients

Kenneth
  • 28,294
  • 6
  • 61
  • 84
  • i think `overrides` shouldbe `override` mightbe a typo :) – Sudhakar Tillapudi Mar 10 '14 at 13:46
  • I'm refactoring the classes in a project at work and it's such a mess that I have to do some weird compromises (imagine a class that has 20something vars and a name() that returns the name... by hand. Or a switch-case with a return "" outside it so "the compiler doesn't throw an error". This is in the code too). The final code should be cleaner but this solution is a provisional one). – bufalo1973 Mar 11 '14 at 12:53
-2

Either you have to override Something() in Class B or get result of obj.something(); in Class A's Object.

Naresh Parmar
  • 462
  • 3
  • 16