Проблема со ссылками на объекты

#c# #class #reference #copy

#c# #класс #ссылка #Копировать

Вопрос:

Мой вопрос будет довольно последовательным.

У меня есть универсальный класс Cell<T> . И у меня есть клиентский класс, который работает с двумерным массивом Cell<T> :

 public sealed class Environment
{
    private Cell<YUV>[,] primaryLayer;        

    public Colorizator(Cell<YUV>[,] layer)
    {
        // initialization...
    }
// ...
}
  

В Environment классе я вызываю метод, который выполняет следующее:

 for(var ix = 1; ix < this.Width - 1; ix  )
{
    for(var iy = 1; iy < this.Height - 1; iy  )
    {
        this.primaryLayer[ix, iy].Window[0] = this.primaryLayer[ix - 1, iy   1];
        this.primaryLayer[ix, iy].Window[1] = this.primaryLayer[ix, iy   1];
        this.primaryLayer[ix, iy].Window[2] = this.primaryLayer[ix   1, iy   1];
        this.primaryLayer[ix, iy].Window[3] = this.primaryLayer[ix   1, iy];
        this.primaryLayer[ix, iy].Window[4] = this.primaryLayer[ix   1, iy - 1];
        this.primaryLayer[ix, iy].Window[5] = this.primaryLayer[ix, iy - 1];
        this.primaryLayer[ix, iy].Window[6] = this.primaryLayer[ix - 1, iy - 1];
        this.primaryLayer[ix, iy].Window[7] = this.primaryLayer[ix - 1, iy];
    }
}
  

Это заполняет каждую ячейку по соседству с соседом.

Затем я использую алгоритм, аналогичный заливке другим методом:

 foreach(var cell in some_list)
{
    Parent = cell;
    Parent.Conquer(Parent);
    Parent.ViabilityRatio = this.ViabilityTresholds.Max;

    lr[Parent.X, Parent.Y] = Parent;

    while(true)
    {
        if(null == (Child = Parent.Window.FirstOrDefault(x => !(x as Cell<YUV>).IsMarked) as Cell<YUV>))
        {
            break;
        }
        else
        {
            Parent.Mark(Child);               

            var wt = default(Double);
            foreach(Cell<YUV> ch in Child.Window)
            {
                // Operation fails   
                // NullReferenceException occurs: there's no cells in `Child` neighbourhood
                wt  = ch.ViabilityRatio;
            }

            Parent = Child;
        }
    }
} 
  

Когда я пытаюсь выполнить итерацию Child.Window , я обнаружил, что нет элементов соседства. Первая мысль заключалась в том, что Parent и Child особенно Child не сохранять ссылки на объекты, которые я им назначил. Я имею в виду, что cell переменная in the foreach loop имеет ненулевую окрестность. Но родительский элемент этого не сделал.

Решение 1. Помогло с родительской ячейкой

Я реализовал Copy метод в Cell<T> классе:

 public Cell<T> Copy()
{
    return (Cell<T>)this.MemberwiseClone();
} 
  

С тех пор Parent сохраняется его свойство not-null Window .

 foreach(var cell in some_list)
{
    Parent = cell.Copy();
  

Но if(null == (Child = Parent.Window.FirstOrDefault(x => !(x as Cell<YUV>).IsConquered) as Cell<YUV>).Copy()) пробная версия, к сожалению, завершается неудачей.

Child не имеет свойства not-null Window .

Пожалуйста, помогите!! Спасибо!

Редактировать

Я попытался сделать следующее:

var ActiveWindow = (from ch in Parent.Window select (Cell<YUV>)ch).ToList();
ActiveWindow коллекция поддерживает инициализацию всех соседей. Более того, у всех соседей, как я и ожидал, инициализированы свои собственные соседи.

Но когда я отладил это: Child = ActiveWindow[0] Child не хранит соседей..

Правка 2

Child ячейка не равна нулю. Я получаю исключение внутри else предложения.

Это то, что я получил с моей Child ячейкой:введите описание изображения здесь

И это то, что я получил с Parent ячейкой:

введите описание изображения здесь

Комментарии:

1. Это монстр C пришел, чтобы съесть ваш стиль кодирования. Омм ном ном.

Ответ №1:

Надеюсь, я ничего не понял неправильно, от этих утверждений у меня болят глаза: P

Скажем, Parent.Window не содержит ничего Window , что не было бы захвачено, тогда

Parent.Window.FirstOrDefault(x => !(x as Cell<YUV>).IsConquered) as Cell<YUV>

Поскольку ни один элемент не соответствует шаблону, не существует First , и default(Cell<YUV>) возвращает null .

Пересмотрите это утверждение:

if (null == (Child = Parent.Window.FirstOrDefault(x => !(x as Cell<YUV>).IsConquered) as Cell<YUV>).Copy())

Привело бы к:

if (null == (Child = null).Copy())

Или:

if (null == null.Copy())

Поскольку для Copy() метода нет ссылки на объект, и будет выдано исключение.

Комментарии:

1. У меня есть решетка Cell<T> , а затем я заполняю массив ICell<T> типа переменными решетки, т.е. Cell<T> .

2. @helicera: Я обновил свой ответ, поскольку считаю, что в дополнительных случаях с указанным вами утверждением может возникнуть «проблема с нулем». Я не знаком с вашим кодом, поэтому я изучал исключительно синтаксис C #.

3. Возможно, вы правы, говоря, что виной всему мое ужасное утверждение, но во время отладки я проверил Child значение, и оно не равно null. Я добавлю для вас некоторое изображение в свою правку, поскольку мне трудно описать, что именно я имею в виду. Window — это всего лишь массив ячеек, расположенных на расстоянии 1 ячейки относительно родительской ячейки, таким образом, имеется 8 дочерних ячеек. Я почти уверен, что каждая ячейка, принадлежащая моей решетке, заполнена окнами.