当前位置: 首页 > 编程语言 > C#

Listinc#Share

时间:2023-04-10 11:26:32 C#

Listinc#我无法理解List背后的逻辑,因为它打破了一些基本规则。列表应该是值类型而不是引用类型。如果必须在函数调用之间维护其值,则必须通过ref关键字传递列表。所以这意味着它显示出类似int的值类型行为。但List必须由new运算符初始化。列表也可以为空。这意味着引用类型行为。可空类型不同,因为它不必由new运算符初始化。我读错了吗?编辑-我应该在原始问题中发布代码。但它遵循-namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){ListTestd=newListTest();d.测试();}}classListTest{publicvoidModifyIt(Listl){l=returnList();}publicvoidTest(){ListlistIsARefType=newList();修改它(listIsARefType);Console.WriteLine(listIsARefType.Count);//应该是1但实际上是0Console.ReadKey(true);}publicListreturnList(){Listt=newList();t.Add(1);返回吨;}}}列表应该是值类型而不是引用类型。错误!int是一种值类型。列表是引用类型。我认为您的第一个项目符号中存在错误的假设。通用List对象肯定是引用类型(在堆上,而不是堆栈上)。不知道为什么你认为你必须通过参考。这会像它应该的那样打印“2”:namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){修改它(listIsARefType);修改它(listIsARefType);Console.WriteLine(listIsARefType.Count);//2!控制台.ReadKey(true);}staticvoidModifyIt(Listl){l.Add(0);你需要了解按引用传递、按值传递和按值传递的区别。在您发布的代码示例中,您正在按值传递对List对象的引用。这意味着您可以更改引用指向的对象,并且调用代码将看到这些更改。但是,引用本身是按值传递的,因此如果您将引用更改为指向另一个对象,调用代码将看不到更改。当您使用ref关键字时,您是通过引用传递引用。这意味着您不仅可以更改引用指向的内容,还可以更改引用本身。考虑这个例子:classProgram{staticvoidMain(){intfoo=0;DoSomething1(foo);控制台.WriteLine(foo);//输出0.DoSomething1(reffoo);控制台.WriteLine(foo);//输出1.varbar=newList();DoSomething2(酒吧);Console.WriteLine(bar.Count);//输出1.DoSomething2(refbar);Console.WriteLine(bar.Count);//输出0。}//按值传递。staticvoidDoSomething1(intnumber){//不能修改数字!数字++;}//按值传递。staticvoidDoSomething1(refintnumber){//可以修改数字!数++;}//按值传递引用。staticvoidDoSomething2(Listlist){//不能改变引用,但可以改变对象。列表。添加(25);}//通过引用传递引用。staticvoidDoSomething2(refListlist){//可以更改引用(并改变对象)。列表=新列表();}}不要把它想成一个List,把它写成一个List。列表是一个泛型类。它不是一个结构。它是一个通用类,可以使用值类型和引用类型。List确实是一个引用类型。但是列表中包含的项目是值类型。但是,可为Nullable的类型实现为结构(structNullablewhereT:struct),因此是值类型。为什么可以简单的写int?我=3;如果没有new关键字,编译器会自动将上述语法转换为执行以下操作的代码:Nullablei=newNullable(3);为了更好地理解值类型和引用类型语义之间的区别,我建议你阅读JonSkeet关于这个主题的文章,它会给你很多示例代码示例:JonSkeet:ParameterpassinginC#Listisagenericreferencetype,你使用了一个类型,它的值类型是int。但它仍然是一个引用类型。列表是引用类型。而且它不必作为参考传递。列表中对象的类型是值类型,除了值类型对象最终可以被装箱(转换为类型的引用类型对象),所以...理解后抓住这一段。除了其他答案中处理的错误假设外,您还说:Listmustbeinitializedbynewoperator...这意味着引用类型行为。不,在C#中,new运算符只是调用类型构造函数的语法。它用于引用和用户定义的值类型(struct)。在ModifyIt()方法中,当你写'l=returnList()';“l”现在指向内存中与Test()方法中的listIsARefType位置不同的位置。基本上通过写'l"='something,你已经打破了'l'和'listIsARefType'之间的链接。为了保持链接(确保两个对象,'l'和'listIsARefType'指向内存中的相同位置),您只需要处理“l”对象(例如,通过调用对象上的函数),或者在ModifyIt()方法的参数中使用ref关键字。以上就是C#学习教程:列出所有在c#中分享的内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处: