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.
In C++, a derived class object can be assigned to a base class object, but the other way is not possible.
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.
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.
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With