Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何通过列表<;DerivedClass>;参数类型为列表时<;基类>;?_C#_Derived Class_Generic List_Ref - Fatal编程技术网

C# 如何通过列表<;DerivedClass>;参数类型为列表时<;基类>;?

C# 如何通过列表<;DerivedClass>;参数类型为列表时<;基类>;?,c#,derived-class,generic-list,ref,C#,Derived Class,Generic List,Ref,我如何传递一个列表,它是一个DerivedObjects列表,而方法需要一个BaseObjects列表。我正在转换列表.ToList(),不知是否有更好的方法。我的第二个问题是语法不正确。我试图通过byref传递列表,但出现错误:'ref'参数未分类为变量 如何解决这两个问题?谢谢 public class BaseClass { } public class DerivedClass : BaseClass { } class Program { static void Main(s

我如何传递一个列表,它是一个DerivedObjects列表,而方法需要一个BaseObjects列表。我正在转换列表
.ToList()
,不知是否有更好的方法。我的第二个问题是语法不正确。我试图通过byref传递列表,但出现错误:
'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);
    }
}
公共类基类{}
公共类DerivedClass:基类{}
班级计划
{
静态void Main(字符串[]参数)
{
List myDerivedList=新列表();
PassList(ref myDerivedList.ToList());
//上面的语法错误是-“ref”参数未分类为变量
Console.WriteLine(myDerivedList.Count);
}
公共静态无效密码列表(参考列表myList)
{
添加(新的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);
}
publicstaticvoidpasslist(reflistmylist),其中T:BaseClass
{
如果(myList==null)myList=new List();
//对不起,我知道我在上面的例子中遗漏了这个。
var x=Activator.CreateInstance(typeof(T),新对象[]{})作为T;
添加(x);
Console.WriteLine(myList.Count);
}

感谢所有帮助解答此问题和其他SO问题的人。

如果您必须保留
ref
,您可以执行以下操作:

var list = myDerivedList.ToList<BaseClass>();
PassList(ref list);
// SYNTAX ERROR ABOVE IS - 'ref' argument is not classified as a variable
var list=myDerivedList.ToList();
密码列表(参考列表);
//上面的语法错误是-“ref”参数未分类为变量

对于
ref
参数,它需要引用一个变量。动态创建时,代码中没有任何内容可供以后引用,因此它实际上毫无意义。

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

List<BaseClass> tmp = myDerivedList.ToList<BaseClass>();
PassList(ref tmp);
现在,这将尝试将
DerivedClass
的一个实例添加到
列表中
——这就像将一个苹果添加到一堆香蕉中一样。。。它不起作用!C#编译器阻止你执行这种不安全的操作——它不会让你把一串香蕉当作水果碗。假设我们有
水果
而不是
基类
,还有
香蕉
/
苹果
作为两个派生类,其中
密码列表
向给定的列表中添加了一个
苹果

// 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 );    
//这很好-你可以将一个苹果添加到水果碗中,没有问题
List fruitBowl=新列表();
通行证(果盘);
//这不会编译,因为编译器在PassList中不“知道”
//你实际上只是在添加一个苹果。
List bagOfApples=新列表();
通行证列表(bagOfApples);
//这是一种危险的情况,你会试图真正违反
//键入safety,将非香蕉插入一串香蕉中。但是编译器
//无法区分此项与前一项的区别,仅基于
//事实上,您正在尝试将一个列表转换为一个列表
List bunchOfBananas=新列表();
通行证列表(bunchOfBananas);

C#4允许在某些情况下出现通用差异——但在这种特殊情况下没有帮助,因为你正在做一些根本不安全的事情。不过,泛型差异是一个相当复杂的话题——由于您仍在学习参数传递的工作原理,我强烈建议您暂时不要讨论它,直到您对语言的其余部分更有信心为止。

首先,在您提供的代码中,您不需要
ref
,因为您实际上没有以任何方式更改destination(reference)myList。 当然,您会在
ref myDerivedList.ToList()
中遇到一个错误,因为使用byref可以更改变量指向的位置,但不提供变量,而是提供一个值(因此只需阅读编译器代码即可)


针对您的观点:阅读关于-如果您使用的是.net 4.0

为什么在这种情况下需要
ref
?ref是必需的,否则添加的项目将与方法一起装箱。(希望我正确理解了这些术语)。
List
是一个参考类型类。方法中添加的项将添加到同一实例。@Valamas:不,您不了解
ref
的工作原理(或者可能不了解引用类型的工作原理)。按照我答案中的链接仔细阅读,我以前没有见过“where T:BaseClass”语法,这很有用。感谢您发布已解决的代码。为Jon的解释和您网站的链接干杯。我已经用泛型解决了我的问题。我可以问一下什么
List tmp=myDerivedList.ToList()是否准确?它是创建副本还是什么?我也有类似的需求,而且——令我惊讶的是——如果我这样做并将结果传递给我的方法,对对象所做的更改将反映在原始列表中。(我正在修改对象,而不是从列表中添加或删除任何内容。)@JonathanWood:它创建了列表的浅副本。因此,在副本中不会看到对原始列表的添加和删除更改,但会看到对对象的更改,因为新列表包含对相同对象的引用。
// 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 );