#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 дочерних ячеек. Я почти уверен, что каждая ячейка, принадлежащая моей решетке, заполнена окнами.