Reputation: 201
I am new to using C#. I am most familiar with C++ and Java when it comes to Object-Oriented Programming and polymorphism. Can someone tell me why this upcast does not work in C#, and what I can do to get the upcast to work with ref.
using System;
public class ParentClass
{
public int i;
}
public class ChildClass : ParentClass
{
public char a;
}
public class Program
{
static void TryMe(ref ParentClass parent)
{
}
static ChildClass child = new ChildClass();
public static void Main()
{
TryMe(ref child);
Console.WriteLine("Hello World");
}
}
Upvotes: 0
Views: 88
Reputation: 33863
Your issue is caused by your usage of ref
, which the C# spec defines as:
A parameter declared with a ref modifier is a reference parameter.
A reference parameter does not create a new storage location. Instead, a reference parameter represents the same storage location as the variable given as the argument in the function member, anonymous function, or local function invocation. Thus, the value of a reference parameter is always the same as the underlying variable.
If the type is modified as part of the call, it can no longer be the same underlying variable.
Passing the reference by value does not have the same restriction:
TryMe(child);
Console.WriteLine("Hello World");
static void TryMe(ParentClass parent)
{
}
static ChildClass child = new ChildClass();
public class ParentClass
{
public int i;
}
public class ChildClass : ParentClass
{
public char a;
}
As mentioned in the comments, you either need to remove ref
and pass the references by value, or you need to include methods for all polymorphic cases:
TryMe(ref child);
TryMe(ref parent);
static void TryMe(ref ParentClass parent) { }
static void TryMe(ref ChildClass parent) { }
static ChildClass child = new ChildClass();
static ParentClass parent = new ParentClass();
public class ParentClass
{
public int i;
}
public class ChildClass : ParentClass
{
public char a;
}
Upvotes: 1
Reputation: 6620
Your static field child
is of type ChildClass
. Classes are reference types, so the child
property is a reference to an instance of ChildClass
. All instances of ChildClass
are also instances of ParentClass
, but not vice-versa.
When you pass a reference type by reference, in C#'s model you're really passing the child
field itself. As in, you may re-assign that field in the callee:
static void TryMe(ref ParentClass parent)
{
parent = new ParentClass();
}
This is perfectly valid for this individual method - but in our context, it would cause a problem, because when we reassign parent
here, we're actually reassigning the child
field... and the child
field says it must be an instance of ChildClass
, which it wouldn't be the case here - it's an instance of ParentClass
only.
So, the type system prohibits you from passing a ref
to a subtype of the method's parameter's type.
Upvotes: 0