C# .NET通用列表<;T>;问题是设计出来的,需要解决。添加值而不是引用

C# .NET通用列表<;T>;问题是设计出来的,需要解决。添加值而不是引用,c#,.net,generics,generic-programming,C#,.net,Generics,Generic Programming,我有一个列表,我需要避免我将要概述的行为: // assume cls and numberToAdd are parameters passed in. int pos = numberToAdd; List<MyClass> objs = new List<MyClass>(numberToAdd); for(int i = 0; i < numberToAdd; i++) { objs.Add(cls)

我有一个
列表
,我需要避免我将要概述的行为:

    // assume cls and numberToAdd are parameters passed in.
    int pos = numberToAdd;
    List<MyClass> objs = new List<MyClass>(numberToAdd);

    for(int i = 0; i < numberToAdd; i++)
    {
        objs.Add(cls);
        objs[i].X = -((pos * cls.Width) + cls.Width / 2);
        pos--;
    }

    Console.WriteLine(objs[0].X + "\r\n" + objs[1].X);
//假设cls和numberToAdd是传入的参数。
int pos=数字相加;
List objs=新列表(numberToAdd);
for(int i=0;i
这将导致此writeline打印相同的值


基本上,我需要的是更改“Add”方法的行为。我想添加一个具有相同值的对象的新实例,而不仅仅是对相同对象的引用。我知道这会占用更多内存。

什么是“cls”变量?只需在每个循环中创建一个新循环。你想做的是克隆它;但老实说,这会让人困惑。我建议只为每个循环创建一个新循环

--编辑

注意到您对“cls”的评论

我建议你克隆它然后(假设你不能改变呼叫和做我的上述建议)。要做到这一点,只需创建一个新的,并复制所有的属性

通常,如果您可以控制“cls”类型,则只需创建一个“复制”构造函数。是这样的:

class Foo {
    private int x;

    public Foo (Foo toCopy) {
       this.x = toCopy.x;
    }

    ...
}

可能希望扩展cls以包含克隆方法。如果不能修改cls类,扩展方法将起作用

然后改变 对象添加(cls); 到
Add(cls.Clone())

啊。您需要将cls实现为一个结构,以便它显示按值传递语义

或者,您需要在cls对象上实现一个克隆方法,这样您就可以创建一个方法来克隆该对象,从而创建对该对象的新引用,以便执行此操作

即使您没有访问对象本身的权限,也可以创建一个扩展方法来实现这一点

public cls Clone(this cls)
{
    //initialise the object to clone it.
    return new cls(this.param1, this.param2,...) 
}

看起来像是同一个对象,cls正在添加numberToAdd times到列表中

您需要在循环中创建对象的新实例

for(int i = 0; i < numberToAdd; i++)
{
    MyClass c=new MyClass(...);
    c.X = -((pos * c.Width) + c.Width / 2);
    objs.Add(c);
    pos--;
}
for(int i=0;i
让MyClass实现,然后简单地使用

objs.Add((MyClass)cls.Clone());

我认为ICloneable.Clone()会返回一个对象,因此在将对象添加到列表之前,需要进行强制转换。最终完成了此操作,但使用的是一种方法而不是构造函数——其中一种方法有优势吗;不管怎样都没关系。构造函数将保证在您可以对其执行任何操作之前,您拥有一个完全克隆的对象。该方法可能意味着您的对象在调用“.Clone()”之前是空的,但这也没关系。