如何传递List当参数类型为 List时?

发布于 2024-12-07 22:03:30 字数 1240 浏览 3 评论 0原文

我如何传递一个列表,该列表是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绮筵 2024-12-14 22:03:30

ref 部分很简单:要通过引用传递参数,它基本上必须是一个变量。所以你可以这样写:

List<BaseClass> tmp = myDerivedList.ToList<BaseClass>();
PassList(ref tmp);

...但这不会影响myDerivedList的值或内容本身。

无论如何,此处的 ref 毫无意义,因为您永远不会在方法内更改 myList 的值。了解更改参数值和更改参数值引用的对象的内容之间的区别非常重要。有关更多详细信息,请参阅我关于参数传递的文章

现在至于为什么你不能传递你的列表 - 这是为了保持类型安全。假设您可以这样做,并且我们可以这样写:

List<OtherDerivedClass> list = new List<OtherDerivedClass>();
PassList(list);

现在尝试将 DerivedClass 的实例添加到 List -这就像在一堆香蕉中添加一个苹果一样......这是行不通的! C# 编译器会阻止您执行不安全的操作 - 它不会让您将一堆香蕉视为水果盘。假设我们有 Fruit 而不是 BaseClass,并且 Banana / Apple 作为两个派生类,使用 PassListApple 添加到它给出的列表中:

// 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 在某些情况下允许通用方差 - 但这没有帮助在这种特殊情况下,因为你正在做一些根本性的事情不安全。不过,通用方差是一个相当复杂的主题 - 由于您仍在学习参数传递的工作原理,我强烈建议您暂时不要理会它,直到您对其余部分更有信心为止语言的。

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);

... 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 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);

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 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.

请持续率性 2024-12-14 22:03:30

如果必须保留ref,可以这样做:

var list = myDerivedList.ToList<BaseClass>();
PassList(ref list);
// SYNTAX ERROR ABOVE IS - 'ref' argument is not classified as a variable

对于ref参数,它需要一个变量来引用。当动态创建时,稍后在代码中没有任何内容可以引用,因此它确实没有任何意义。

If you must keep the ref, you can do this:

var list = myDerivedList.ToList<BaseClass>();
PassList(ref list);
// SYNTAX ERROR ABOVE IS - 'ref' argument is not classified as a variable

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.

第几種人 2024-12-14 22:03:30

首先,在您提供的代码中,您不需要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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文