Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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#结构化列表_C#_List_Struct - Fatal编程技术网

C#结构化列表

C#结构化列表,c#,list,struct,C#,List,Struct,我对这段代码有问题 我有这个结构 public struct bounds { public int xmax = 0; public int xmin = 0; public int ymax = 0; public int ymin = 0; }; 我把它列了个清单 List<bounds> map = new List<bounds>(); List map=newlist();

我对这段代码有问题

我有这个结构

public struct bounds
{
        public int xmax = 0;
        public int xmin = 0;
        public int ymax = 0;
        public int ymin = 0;        
};
我把它列了个清单

List<bounds> map = new List<bounds>(); 
List map=newlist();
我试图将一个空间(或对象)的边界存储在一个2D数组中(它的xmax、xmin、ymin和ymax)。我有一个整数y变量,当它到达这个代码时,它将是一个数字,但我在与我的列表“map”相关联的代码下不断得到红线(I和j是通过2D数组的计数器)

if(!(map.Contains(y))//如果列表中还没有此编号
{    
地图。添加(y);
映射[y].xmax=i;//并设置其xmax、xmin、ymax、ymin
map[y].xmin=i;
map[y].ymax=j;
map[y].ymin=j;
}
if(map[y].xmaxj)
map[y].xmin=j;
if(map[y].ymaxj)
map[y].ymin=i;

要使用
列表
索引器,需要传递一个int。这里传递的是
边界
结构

map[y].xmax = i;
y
必须是表示要访问的索引的整数。我猜
y
是一个边界结构,因为您使用了

map.Add(y);

而您的
映射
类型为
列表
要使用
列表
索引器,您需要传递一个int。您在这里传递的是
边界
结构

map[y].xmax = i;
y
必须是表示要访问的索引的整数。我猜
y
是一个边界结构,因为您使用了

map.Add(y);

而您的
映射
的类型为
列表

这是因为结构是值类型

当您从列表中读取结构时,您将获得一个副本

因此,这行代码(以及所有类似的代码):

正在修改从列表中获取的副本

您可以通过手动检索副本、修改副本并将其放回列表来解决此问题

注意:可变结构会产生各种各样的问题。您遇到的问题只是其中之一,但您不应该使它们可变

还要注意:您使用struct值本身作为列表的索引器,我假设这是一个错误,并且您实际使用的是一个索引变量,否则您确实会遇到问题

不过这里有一个一般提示。如果VisualStudio正在代码下绘制红色曲线,则可以将鼠标悬停在其上以获得工具提示,告诉您出了什么问题。这对您来说可能很神秘,但通过谷歌搜索错误消息要容易得多:


原因是结构是值类型

当您从列表中读取结构时,您将获得一个副本

因此,这行代码(以及所有类似的代码):

正在修改从列表中获取的副本

您可以通过手动检索副本、修改副本并将其放回列表来解决此问题

注意:可变结构会产生各种各样的问题。您遇到的问题只是其中之一,但您不应该使它们可变

还要注意:您使用struct值本身作为列表的索引器,我假设这是一个错误,并且您实际使用的是一个索引变量,否则您确实会遇到问题

不过这里有一个一般提示。如果VisualStudio正在代码下绘制红色曲线,则可以将鼠标悬停在其上以获得工具提示,告诉您出了什么问题。这对您来说可能很神秘,但通过谷歌搜索错误消息要容易得多:


如果数据类型的目的是封装一组固定的相关但独立的值(如点的坐标),则公开的字段结构比任何其他数据类型更符合该描述。除了覆盖
ToString()
Equals()
GetHashCode()
之外,这些结构不应该有很多实例方法;通常,结构使用静态实用程序方法比使用实例方法要好。例如,这将是有问题的:

public void UpdateRange(Point pt)
{
   if (pt.X > xmax) xmax = pt.X;
   if (pt.Y > ymax) ymax = pt.Y;
   if (pt.X < xmin) xmin = pt.X;
   if (pt.Y < ymin) ymin = pt.Y;
}
如果UpdateRange是一个实例方法,那么也不能使用:

myList[4].UpdateRange(newPoint);
在后一种情况下,代码可以编译,但无法工作。相反,我们必须使用以下内容:

bounds.UpdateRange(ref myList[4], newPoint);
var temp = myList[4];
bounds.UpdateRange(ref temp, newPoint);
mylist[4] = temp;
请注意,实例方法和带有
ref
参数的静态方法在语义上是相同的,这两种方法都将编译。它们之间的区别在于,带有
ref
参数的静态方法仅在
ref
参数是可修改变量的情况下编译,但对属性调用实例方法将导致编译器将该属性复制到临时变量,调用该属性的实例方法,并丢弃结果

我认为你的类型几乎是一个完美的例子,应该是一个结构。如果它是一个可变的类类型,则不清楚向实例传递引用的代码何时真正传递了实例在调用时碰巧持有的瞬时值,或者何时向“活动”实体传递引用。使用不可变的类类型或所谓的不可变的结构类型[请注意,实际上没有不可变的值类型]会使
UpdateRange
之类的方法的编写和运行速度变慢,但没有特别的好处

关于结构类型,需要注意的一点是,每个字段(例如,
xmin
)除了“存储在xmin中的最后一个值”之外没有其他意义,如果尚未存储任何内容,则为零。如果代码将256写入
xmin
并将-234写入
xmax
,则
xmin
将保存256和
xmax-234。任何接受
bounds`并对其执行任何操作的代码都应该为这些值做好准备,就像它将这些字段作为四个单独的参数一样。

如果
var temp = myList[4];
bounds.UpdateRange(ref temp, newPoint);
mylist[4] = temp;