如何传递List< DerivedClass>当参数类型为List< BaseClass>时? [英] How to pass List<DerivedClass> when param type is List<BaseClass>?
问题描述
我如何传递一个列表,该列表是DerivedObjects的列表,其中该方法需要一个BaseObjects的列表。我正在转换列表 .ToList< BaseClass>()
,并且想知道是否有更好的方法。我的第二个问题是语法不正确。我正在尝试通过列表byref,但出现错误:'ref'参数未归类为变量
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);
}
}
已解决:
与此类似的方法解决了我的问题。
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);
}
感谢所有在此问题以及其他SO问题上提供帮助的人。 / p>
Thank you to all who help across this question and from other SO questions.
推荐答案
ref
部分很简单:通过引用传递参数,基本上,它必须是一个变量。因此,您可以这样写:
The ref
part is easy: to pass an argument by reference, it has to be a variable, basically. So you can write:
List<BaseClass> tmp = myDerivedList.ToList<BaseClass>();
PassList(ref tmp);
...但不会影响 myDerivedList
或内容本身。
... but that won't affect either the value of myDerivedList
or contents itself.
此处的 ref
毫无意义。无论如何,因为无论如何都不会在方法中更改 myList
的值。重要的是要了解更改参数值和更改参数值引用的对象内容之间的区别。有关更多详细信息,请参见我关于参数传递的文章。
The ref
here is pointless anyway, as you're never changing the value of myList
within 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:
List<OtherDerivedClass> list = new List<OtherDerivedClass>();
PassList(list);
现在将尝试添加 DerivedClass $ c的实例$ c>到
List< OtherDerivedClass>
中-就像在一个香蕉束中加入一个苹果一样……不起作用! C#编译器阻止您执行这种不安全的操作-它不会让您将一堆香蕉当作水果碗。假设我们 did 有水果
而不是 BaseClass
和香蕉
/ Apple
作为两个派生类,其中 PassList
添加了苹果
到给出的列表中:
Now that would be trying to add an instance of DerivedClass
to a List<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 have Fruit
instead of BaseClass
, and Banana
/ Apple
as two derived classes, with PassList
adding an Apple
to the list it's given:
// This is fine - you can add an apple to a fruit bowl with no problems
List<Fruit> fruitBowl = new List<Fruit>();
PassList(fruitBowl);
// This wouldn't compile because the compiler doesn't "know" that in PassList
// you're only actually adding an apple.
List<Apple> bagOfApples = new List<Apple>();
PassList(bagOfApples);
// This is the dangerous situation, where you'd be trying to really violate
// type safety, inserting a non-Banana into a bunch of bananas. But the compiler
// can't tell the difference between this and the previous one, based only on
// the fact that you're trying to convert a List<Banana or Apple> to List<Fruit>
List<Banana> bunchOfBananas = new List<Banana>();
PassList(bunchOfBananas );
C#4在某些情况下允许通用方差-但它不会在这种特殊情况下提供帮助,因为您所做的事情从根本上来说是不安全的。泛型差异是一个相当复杂的话题-由于您仍在学习参数传递的工作原理,因此我会强烈建议您暂时不要理会它,直到对其余部分更加有信心为止语言。
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.
这篇关于如何传递List< DerivedClass>当参数类型为List< BaseClass>时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!