Как я копирую случай объекта?

Я пытаюсь написать некоторый код, который населяет a List (на самом деле это - серия Lists, но мы можем притвориться, что это всего один List). Идея состоит в том, чтобы добавить IPackage к List для общего количества IPackage на заказе. См. следующий кодекс:

        ParseExcel pe = new ParseExcel();
        Pinnacle p = pe.ParsePinnacleExcel();
        Rack r = new Rack(20,2,4.5,96,42,6,25*12);
        foreach (PinnacleStock ps in p.StockList.Where(x => 
                 x.ColorCode == "10" && 
                 x.PackageLength == 30.64))
        {
            for (int i = 1; i <= ps.OnOrder; i++)
            {
                r.TryAddPackage((IPackage)ps);
            }
        }

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

Что я должен сделать, чтобы гарантировать, что копия объекта вставлена в список и не только дополнительную ссылку?

14
задан Ben McCormack 21 January 2010 в 03:28
поделиться

4 ответа

Затем вам нужно реализовать Iclonable и заменить

r.TryAddPackage((IPackage)ps);

с

r.TryAddPackage((IPackage)ps.Clone());

, решать, как клон должен заполнить новый экземпляр из Pannaclestock , что он возвращается.

На самом базовом уровне вы можете сказать

public PinnacleStock : ICloneable {
    public PinnacleStock Clone() {
        return (PinnacleStock)this.MemberwiseClone();
    }
    object ICloneable.Clone() {
        return Clone();
    }
    // details
}

Это просто сделает неглубокую копию Pinnaclestock . Только вы знаете, если это правильная семантика для вашего домена.

13
ответ дан 1 December 2019 в 12:26
поделиться

Как сказал другие, вам нужно было бы сделать , что копию, в какой-то специфическом ущерблении:

foreach (PinnacleStock ps in p.StockList.Where(x => x.ColorCode == "10" && 
                                                    x.PackageLength == 30.64))
{
  for (int i = 1; i <= ps.OnOrder; i++)
  {
    PinnacleStock clone = ps.CopySomehow();  // your problem
    r.TryAddPackage((IPackage)clone);
  }
}

Однако вы можете допросить вопрос о том, является ли это правильное решение. Вам действительно нужен отдельный экземпляр Pinnaclestock? Добавляет Pinnaclestock в стойку, действительно создает новый, независимый экземпляр? Вы планируете изменить или отслеживать каждый из этих отдельных копий отдельно? Это правильно, что теперь у вас будет экземпляры Pinnaclestock, которые не появляются в вашем учете? Не зная своего домена или семантики Punnaclestock, трудно быть уверенным, но вы можете посмотреть, скажем, создавая объект Pinnaclestockrackentry для представления экземпляра Pinnaclestock - зависит от предполагаемой семантики курса!

3
ответ дан 1 December 2019 в 12:26
поделиться

Вы должны поставить логику, чтобы скопировать объект самостоятельно. .NET не имеет глубокой копии встроенного в любом месте (с заметным потенциальным исключением сериализации). Наиболее близким, является методом MemberWiseclone (), но даже что будет копировать ссылки на любые члены вашего типа, которые являются самими типом ссылки.

2
ответ дан 1 December 2019 в 12:26
поделиться
-

Если вам нужна неглубокая копия, то вы можете написать метод быстрого исправления клона:

public class PinnacleStock : ICloneable
{
    public PinnacleStock Clone()
    {
        return (PinnacleStock)this.MemberwiseClone();
    }

    object ICloneable.Clone()
    {
        return Clone();
    }

    // Other methods
}

Если вам нужна глубокая копия (т. Е. Если Pinnaclestock -объекты, которые вы хотите быть скопированы), то вам нужно будет написать один самостоятельно.

5
ответ дан 1 December 2019 в 12:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: