Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why wont reference of derived class work for a method requiring a reference of base class?

Tags:

c#

I get a compiler error below. I dont know why I cant take a reference of a derived class and pass it to a method which takes a reference of the base class. Note that methods foo() and bar() doesnt necessarily have the same semantics so they should have different names, these methods are not the issue.

public class X { public int _x; }  
public class Y : X { public int _y; }  

public class A {  
  public void foo( ref X x ) {  
    x._x = 1;  
  }  
}  

public class B : A {  
  public void bar( ref Y y ) {  
    foo( ref y ); // generates compiler error
    foo( ref (X)y); // wont work either
    y._y = 2;  
  }  
}

The only solution I found was:

public class B : A {  
  public void bar( ref Y y ) {  
    X x = y;
    foo( ref x ); // works
    y._y = 2;  
  }  
}

I know "y" is never initialized in bar() but since its declared as ref itself must be initialized outside the method so that cant be the problem. Any illumination you can shed on this matter would be helpful. I'm sure its just my understanding of C# thats lacking, this would work in C++ with a cast.

like image 676
Timo Avatar asked Oct 29 '09 10:10

Timo


People also ask

Can a derived class reference to base class object?

In C++, a derived class object can be assigned to a base class object, but the other way is not possible.

Why would one create a base class object with reference to the derived class?

One reason for this could be that BaseClass is abstract (BaseClasses often are), you want a BaseClass and need a derived type to initiate an instance and the choice of which derived type should be meaningful to the type of implementation.

Can we have same method in base and derived class in C#?

In C#, a method in a derived class can have the same name as a method in the base class. You can specify how the methods interact by using the new and override keywords. The override modifier extends the base class virtual method, and the new modifier hides an accessible base class method.


2 Answers

I know that this is a very old question, but seeing as I was trying to find a solution to this problem and couldn't, I'm deciding to post a quick workaround for any people who decide to visit this question in the future. The best way to circumnavigate C#'s type system is to use templating/generic types to your advantage:

public class A {
  public void foo<T>( ref T x ) where T : X {  
    x._x = 1;  
  }  
}  

public class B : A {  
  public void bar( ref Y y ) {  
    foo<Y>( ref y ); // works now
    y._y = 2;
  }  
}

Now the function foo extends to all of the subclasses of type X, but you have to make sure you supply the correct overarching type.

like image 109
Cristian Zaloj Avatar answered Oct 04 '22 23:10

Cristian Zaloj


Because there's no way to ensure you won't replace the reference with an instance of a type entirely different from what you've passed in the first place.

Given:

class Base
{}

class Hamster : Base
{}

class ADentist : Base
{}


void ohWait(ref Base obj)
{
    obj = new ADentist();
}

When calling it this way:

var foo = new Hamster();
ohWait(ref foo);

would break atrociously. Eric Lippert explains it way better than me in: Why do ref and out parameters not allow type variation?

like image 30
Yann Schwartz Avatar answered Oct 04 '22 21:10

Yann Schwartz