C# 更改集合中的结构

C# 更改集合中的结构,c#,.net,C#,.net,我在里希特的书中读到了拳击,有一件事我不明白。 我已成功更改对象中的struct。但当我试图在集合中更改struct时,我遇到了一个问题 //my struct internal struct Point:IChangeBoxedPoint { public Int32 x, y; public void Change(Int32 x, Int32 y) { this.x = x; this.y = y; } public

我在里希特的书中读到了拳击,有一件事我不明白。
我已成功更改对象中的
struct
。但当我试图在集合中更改
struct
时,我遇到了一个问题

//my struct
internal struct Point:IChangeBoxedPoint
{
    public Int32 x, y;
    public void Change(Int32 x, Int32 y)
    {
        this.x = x;
        this.y = y;
    }

    public override string ToString()
    {
        return String.Format("{0}, {1}", this.x, this.y);
    }
}

public static void Main()
{
    List<Point> a = new List<Point>();
    Point p = new Point();
    p.Change(1, 1);
    Console.WriteLine(p); //write 1, 1
    object o = p;
    Console.WriteLine(o); //write 1, 1
    ((Point)o).Change(2, 2);
    Console.WriteLine(o); //write 1, 1
    ((IChangeBoxedPoint)o).Change(3, 3);
    Console.WriteLine(o); //write 3, 3
    for (int i = 0; i < 10; i++)
    {
        p.x = p.y = i;
        a.Add(p);
    }

    Console.WriteLine(a[0]); //write 0, 0
    ((IChangeBoxedPoint)a[0]).Change(300,300);
    Console.WriteLine(a[0]); //still writes 0,0
}
//我的结构
内部结构点:IChangeBoxedPoint
{
公共Int32 x,y;
公共无效更改(Int32 x,Int32 y)
{
这个.x=x;
这个。y=y;
}
公共重写字符串ToString()
{
返回String.Format(“{0},{1}”,this.x,this.y);
}
}
公共静态void Main()
{
列表a=新列表();
点p=新点();
p、 改变(1,1);
Console.WriteLine(p);//写入1,1
对象o=p;
Console.WriteLine(o);//写入1,1
((点)o)。改变(2,2);
Console.WriteLine(o);//写入1,1
((IChangeBoxedPoint)o).变化(3,3);
Console.WriteLine(o);//写入3,3
对于(int i=0;i<10;i++)
{
p、 x=p.y=i;
a、 加(p);
}
Console.WriteLine(a[0]);//写入0,0
((IChangeBoxedPoint)a[0])。变更(300300);
Console.WriteLine(a[0]);//仍然写入0,0
}

之所以发生这种情况,是因为
struct
s是像原语(
int
short
等)这样的值类型。当您在
对象
中框选
结构
时,它会制作一个单独工作的自身副本。下面是一个简单的例子来说明这一点

Point a = new Point();
Console.WriteLine(a); // 0, 0
a.Change(1, 1);
Console.WriteLine(a); // 1, 1
object b = a;
Console.WriteLine(b); // 1, 1
a.Change(2, 2);
Console.WriteLine(a); // 2, 2
Console.WriteLine(b); // 1, 1
class
vs
struct
如果你想使用引用类型,你不会遇到这个问题,你的程序只会将引用传递给你的单个对象。如果需要引用类型,请使用
而不是
结构

internal class Point : IChangeBoxedPoint
何时使用结构 根据哪些参考文献

除非类型具有以下所有特征,否则不要定义结构:

  • 它在逻辑上表示单个值,类似于基本类型(整数、双精度等)
  • 它的实例大小小于16字节
  • 它是不变的
  • 它不必经常装箱
如果您不知道不可变意味着对象不能更改。因此,实际上,您将
结构
装箱到
接口
中,试图对其进行更改,这与良好做法背道而驰

IChangeBoxedPoint中装箱
通过使用
列表
可以解决您的问题,但这只会将其更改为使用对您的值类型的引用,我的问题是,当您可以将
结构
更改为
时,为什么还要麻烦呢

List<IChangeBoxedPoint> a = new List<IChangeBoxedPoint>();
List a=新列表();
进一步阅读
    • 这似乎是对的:

      Console.WriteLine(a[0]); //write 0, 0 -
      
      就因为您的第一个项目收到了
      i=0

      对于这个代码

       ((IChangeBoxedPoint)a[0]).Change(300,300);
      
      实际上不会更改第一项。 它创建了装箱对象点的新实例,并更改了其值

      试着把它改成

       Point newPoint = new Point();
       newPoint.Change(300,300);
       a[0] = newPoint;
       Console.WriteLine(a[0]); 
      

      您应该将收藏声明为
      List
      ,而不是
      List


      如果您将列表声明为
      list
      ,那么您的值将被装箱/取消装箱到接口或从接口中取出,正如其他人已经声明的那样。但是,如果您有一个接口列表,那么只有当您将值添加到列表中时,才会对其进行装箱,从而允许您根据需要对其进行更改。

      只是澄清一下,is
      Console.WriteLine(a[0])//steel write 0,0
      您需要解释的唯一一行?a集合的类型是什么?@Umesh
      List a=new List()