代码错误:如何在c#中使用点运算符列表,以及列表,类和属性之间的关系

本文关键字:列表 关系 之间 属性 运算符 点运算 错误 代码 | 更新日期: 2023-09-27 17:51:17

我试图找出在我的代码中使用的类型或操作(代码最初是从我的主管那里获得的,并修改为适合我的场景)。它是有效的,但我只需要澄清一些事情,我知道StackOverflow是清除任何疑问的头奖:))。这个想法是使用c#来读取包含四个墙的名称/尺寸信息的XML文件,将所有信息编译成一个类(或列表)…还是两个?我有一些困惑在这里)和实例化这些墙在Unity3d运行时。Unity部分我很擅长,但我需要一些帮助来理解我的c#东西是做什么的。

一个文件,Wall.cs:

 public class Wall
 {
 public string Name { set; get; }
 public float Width { set; get; }
 public float Length { set; get; }
 }

同样,XML文件有父标签"Walls",子标签"Wall"和子标签"Name", "Width", "Length"。

主文件ReadWalls.cs:

public class ReadWalls : MonoBehaviour {
public static List<Wall> ListofWalls = new List<Wall>();
public static List<Wall> ReadWallsXML(){ 

在这个函数中有一堆东西来加载XML,使用XmlNodeList等东西。我真的不太关心这个东西,但如果有人有任何进一步的信息,我不介意!

Then是一个foreach循环,它遍历XML,以便每次分析一个Wall。里面:

{Wall w = new Wall();

下一个嵌套foreach在子标记级别相对于XML一次分析一个类别(名称或维度):

foreach (//code specifying subchild tag level)
{if (XmlNodeid.Name == "Name") {w.Name = XmlNodeid.InnerText;
//Similar if statements for "Width" and "Length", with w.Width and w.Length respectively.} //end of inner foreach
ListofWalls.Add(w);} //end of outer foreach
return ListofWalls;} //end of function
void Start() 
{WallsList = ReadWallsXML();

在start函数中,我想使用Debug.Log将所有信息打印到控制台(名称,长度,宽度)。下面的工作(为了简单起见,只打印名称):

foreach (Wall thiswall in WallsList)
{Debug.Log(thiswall.Name);}

如果我这样做,我得到一个错误

foreach (Wall.Name thiswallsname in WallsList)
{Debug.Log(thiswallsname);}
}//end of class

智能感知告诉我"类型'Name'不存在于类型'Wall "。那么,什么是墙呢?我的理解是,我们初始化它为一个类,具有Name, Length, Width的属性。为了访问属性,我们使用点操作。那沃尔为什么不呢?名称访问已创建的每个Wall对象的Name属性?还有,为什么错误说墙是一个类型?还有一件事,墙是一个列表,类,还是两者兼而有之?Intellisense说它是一个类(ReadWalls.cs的第2行),这是有意义的。但是列表方面在哪里发挥作用呢?它的属性是如何与列表相关的?

请注意,为了(一些)简洁,我删除了大量代码,还更改了一些属性/名称,因为我的实际代码相当长。如果您注意到任何逻辑或语法错误,不要担心,因为代码可以正常工作。这个问题的最后一部分是最重要的:我只需要帮助来分析我的变量/数据的类型。如果我犯了任何其他错误,我很抱歉,如果你还看不出来,我在这里完全是个新手(对StackOverflow、c#、Unity和面向对象编程)。也提前感谢!

代码错误:如何在c#中使用点运算符列表,以及列表,类和属性之间的关系

NameWall类的一个属性,而不是它自己的类型。Name类型为string。此外,当您尝试foreach(Wall.Name thiswallsname in WallsList)时,如果它是正确的类型,则要求该类型列表中的每个项目。我的意思是,你告诉代码,你期望WallsListWall.Name类型的集合,而它实际上是Wall实例的集合。

如果您想访问集合中每个WallName属性,您需要执行以下操作:

foreach(Wall wall in WallsList)
{
   Debug.WriteLine(string.Format("Name: {0}", wall.Name));
}

表明你已经有了一些基本相同的东西

Wall是一个类,WallsList是一个List<Wall>类型。基本上是一个集合类型,因此集合中的每个项都是强类型的Wall。它与您在ListOfWalls上面定义的变量相同。关于List<T>的注释:任何类都可以通过将变量定义为List<ClassName>类型来创建自己的列表,例如List<string>将为您提供string变量列表,List<int>将是整数列表,List<List<int>>将是整数列表……等等。

要打印每个属性的值,您需要在foreach循环中列出每个属性的值:

foreach(Wall wall in WallsList)
{
   StringBuilder sb = new StringBuilder();
   sb.AppendLine(string.Format("Name: {0}", wall.Name));
   sb.AppendLine(string.Format("Width: {0}", wall.Width.ToString()));
   sb.AppendLine(string.Format("Length: {0}", wall.Length.ToString()));
   Debug.WriteLine(sb.ToString());
}
当然,您也可以查看反射,以便在foreach循环中动态地从Wall类中检索属性名称和值的列表,但是如果您已经知道属性名称,那么使用上面的示例将同样有效。

还有,为什么错误说Wall是一个类型?还有一件事是是列表、课程,还是两者都有?

墙是一个类——这里的"type"answers"class"是可以互换的。WallsList,顾名思义,是一个由Wall对象组成的列表。

那为什么沃尔不。命名访问每个墙的Name属性对象?

foreach语句允许您以一种快捷的方式遍历集合(特别是实现IEnumerable接口的任何集合)。最常见的是,您将使用List或Array对象。但是列表和数组都是由创建时声明的特定类型的对象组成的。在这个例子中,你的WallsList对象被定义为List<Wall>:它是一个Wall对象的集合。因此,当foreach迭代遍历时,它只取出每个Wall对象作为一个整体,而不是单个属性。

要访问属性,使用点操作(?)。所以为什么不墙。对每个Wall对象的Name属性进行命名访问创造出来的?

用我能想到的最简单的术语来说,你必须先创建一个类的实例,然后才能访问属性。声明Wall blah = new Wall();在内存中为新对象分配一个空间,然后blah.Name = "hello";设置属性。尝试直接调用Wall.Name = "hello";会导致错误,因为您正在尝试设置从计算机的角度来看不存在的东西。