如何传递List当参数类型为 List时?
我如何传递一个列表,该列表是 DerivedObjects 列表,其中该方法需要 BaseObjects 列表。我正在转换列表 .ToList
并且想知道是否有更好的方法。我的第二个问题是语法不正确。我试图通过引用传递列表,但收到错误:'ref' 参数未分类为变量
如何解决这两个问题?谢谢。
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);
}
}
已解决:
类似的方法已经解决了我的问题。
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);
}
感谢所有帮助解决这个问题和其他问题的人。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
ref 部分很简单:要通过引用传递参数,它基本上必须是一个变量。所以你可以这样写:
...但这不会影响
myDerivedList
的值或内容本身。无论如何,此处的
ref
毫无意义,因为您永远不会在方法内更改myList
的值。了解更改参数值和更改参数值引用的对象的内容之间的区别非常重要。有关更多详细信息,请参阅我关于参数传递的文章。现在至于为什么你不能传递你的列表 - 这是为了保持类型安全。假设您可以这样做,并且我们可以这样写:
现在尝试将
DerivedClass
的实例添加到List
-这就像在一堆香蕉中添加一个苹果一样......这是行不通的! C# 编译器会阻止您执行不安全的操作 - 它不会让您将一堆香蕉视为水果盘。假设我们有Fruit
而不是BaseClass
,并且Banana
/Apple
作为两个派生类,使用PassList
将Apple
添加到它给出的列表中:C# 4 在某些情况下允许通用方差 - 但这没有帮助在这种特殊情况下,因为你正在做一些根本性的事情不安全。不过,通用方差是一个相当复杂的主题 - 由于您仍在学习参数传递的工作原理,我强烈建议您暂时不要理会它,直到您对其余部分更有信心为止语言的。
The
ref
part 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
myDerivedList
or contents itself.The
ref
here is pointless anyway, as you're never changing the value ofmyList
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:
Now that would be trying to add an instance of
DerivedClass
to 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 haveFruit
instead ofBaseClass
, andBanana
/Apple
as two derived classes, withPassList
adding anApple
to 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.
如果必须保留
ref
,可以这样做:对于
ref
参数,它需要一个变量来引用。当动态创建时,稍后在代码中没有任何内容可以引用,因此它确实没有任何意义。If you must keep the
ref
, you can do this:For a
ref
parameter, it needs a variable to reference. When created on-the-fly there's nothing to reference later in code so it really makes no sense.首先,在您提供的代码中,您不需要
ref
,因为您实际上并没有以任何方式更改destination(引用)myList。当然,您会收到
ref myDerivedList.ToList<..>()
的错误,因为使用 byref 您可以更改变量指向的位置,但您不会给出变量,你给出一个值(所以只需阅读编译器抱怨;))给你的观点:阅读关于协方差和逆变 - 如果您使用.net 4.0
First, in the code you provided you don't need the
ref
because you don't really change the destination (reference) myList in any way.Then of course you get an error with the
ref myDerivedList.ToList<..>()
because with a byref you can change where a variable is pointed to, but you don't give a variable, you give a value (so just read the compiler complain ;) )To you point: read about Co- and Contravariance - if you are using .net 4.0