Общий список .NET <T> Проблема, работает по проекту, нужно обойти. Добавить значение вместо ссылки

2

У меня есть List<T>, и мне нужно избегать поведения, которое я собираюсь описать:

    // 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);

Это приводит к тому, что эта сценария печатает одно и то же значение.

В основном мне нужно изменить поведение метода "Добавить". Я хотел бы добавить новый экземпляр объекта с теми же значениями, а не просто ссылку на тот же объект. Я понимаю, что это будет использовать гораздо больше памяти.

Теги:
generics
generic-programming

5 ответов

1
Лучший ответ

Что такое переменная 'cls'? Просто создайте новый внутри каждого цикла. То, что вы хотите сделать, это клонировать его; но, честно говоря, это будет путать. Я бы предложил просто создать новую для каждого цикла.

- Изменить

Заметили, что вы прокомментируете "cls".

Я предлагаю вам клонировать его тогда (предполагая, что вы не можете изменить вызов и сделать мое предложение выше). Сделайте это, просто создав новый и скопировав все свойства.

Как правило, если у вас есть контроль над типом 'cls', вы просто создаете конструктор 'Copy'. Это так:

class Foo {
    private int x;

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

    ...
}
  • 0
    Закончилось этим, но в методе вместо конструктора - есть ли преимущество у одного или другого?
  • 0
    На самом деле, нет; все в порядке в любом случае. Конструктор гарантирует, что у вас есть полностью клонированный объект, прежде чем вы сможете что-либо с ним сделать. Этот метод может означать, что ваш объект заранее пуст, до тех пор, пока вы не вызовете .Clone (), но это тоже хорошо.
1

Может потребоваться расширение cls для включения метода clone. Метод расширения будет работать, если вы не можете изменить класс cls.

затем измените objs.Add(ЦБС);  в objs.Add(cls.Clone());

1

Ах. Вам нужно реализовать cls как структуру, чтобы она проходила по семантике значений.

ИЛИ вам нужно реализовать метод clone для вашего объекта cls, чтобы вы могли создать метод клонирования объекта и, таким образом, создать для него новую ссылку, чтобы вы могли это сделать.

Даже если у вас нет доступа к самому объекту, вы можете создать способ расширения для этого.

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

Имейте MyClass Внедрите ICloneable, а затем просто используйте

objs.Add((MyClass)cls.Clone());
  • 1
    Я думаю, что ICloneable.Clone () возвращает объект, поэтому вам понадобится приведение, прежде чем вы сможете добавить объект в список.
0

Похож на тот же объект, cls получает добавленное числоДля добавления в список.

Вам нужно создать новый экземпляр ваших объектов внутри цикла.

for(int i = 0; i < numberToAdd; i++)
{
    MyClass c=new MyClass(...);
    c.X = -((pos * c.Width) + c.Width / 2);
    objs.Add(c);
    pos--;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню