How can i pass a list which is a list of DerivedObjects where the Method is expecting a list of BaseObjects. I am converting the list .ToList<BaseClass>() and am wondering if there is a better way. My second problem is the syntax is incorrect. I am trying to pass the list byref and i am getting an error: 'ref' argument is not classified as a variable
How can I fix these two problem? thanks.
public class BaseClass { }
public class DerivedClass : BaseClass { }
class Program
{
static void Main(string[] args)
{
List<DerivedClass> myDerivedList = new List<DerivedClass>();
PassList(ref myDerivedList.ToList<BaseClass>());
// SYNTAX ERROR ABOVE IS - 'ref' argument is not classified as a variable
Console.WriteLine(myDerivedList.Count);
}
public static void PassList(ref List<BaseClass> myList)
{
myList.Add(new DerivedClass());
Console.WriteLine(myList.Count);
}
}
Solved:
A method similar to this has solved my issue.
public static void PassList<T>(ref List<T> myList) where T : BaseClass
{
if (myList == null) myList = new List<T>();
// sorry, i know i left this out of the above example.
var x = Activator.CreateInstance(typeof(T), new object[] {}) as T;
myList.Add(x);
Console.WriteLine(myList.Count);
}
Thank you to all who help across this question and from other SO questions.
The
refpart is easy: to pass an argument by reference, it has to be a variable, basically. So you can write:… but that won’t affect either the value of
myDerivedListor contents itself.The
refhere is pointless anyway, as you’re never changing the value ofmyListwithin the method anyway. It’s important to understand the difference between changing the value of a parameter and changing the contents of the object that the parameter value refers to. See my article on parameter passing for more details.Now as for why you can’t pass your list in – it’s to preserve type safety. Suppose you could do this, and we could write:
Now that would be trying to add an instance of
DerivedClassto aList<OtherDerivedClass>– that’s like adding an apple to a bunch of bananas… it doesn’t work! The C# compiler is preventing you from performing that unsafe operation – it won’t let you treat a bunch of bananas as a fruit bowl. Suppose we did haveFruitinstead ofBaseClass, andBanana/Appleas two derived classes, withPassListadding anAppleto the list it’s given:C# 4 allows generic variance in certain situations – but it wouldn’t help in this particular case, as you’re doing something fundamentally unsafe. Generic variance is a fairly complicated topic though – as you’re still learning about how parameter passing works, I would strongly suggest that you leave it alone for the moment, until you’re more confident with the rest of the language.