Нужно объяснение этих битов кодов
Недавно я наткнулся на проект (решатель из 8 головоломок, использующий A* alg), в котором некоторые коды странные для меня, потому что я никогда не видел подобных ранее.
что означает эта строка? что это?!
this[StateIndex]
что это за нотация? я не могу понять это вообще! Я разместил образец класса, чтобы вы могли увидеть его почти все вместе. и еще один вопрос, не правда ли, что класс реализован как StateNode? он использовал только конструктор для инициализации своих полей, и, что еще хуже, объявил их все открытыми! не должен ли он / она внедрить Пропертис для этой задачи?
public enum Direction
{
Up = 1, Down = 2, Left = 3, Right = 4, UpUp = 5, DownDown = 6, LeftLeft = 7, RightRight = 8, Stop = 9
}
class StateNode
{
public int Parent;
public List<int> Childs;
public Direction Move;
public Direction ParentMove;
public byte[,] State;
public byte Depth;
public byte NullRow;
public byte NullCol;
public StateNode()
{ }
public StateNode(int NewParent, Direction NewMove, Direction ParentMove, byte NewDepth, byte NewNullRow, byte NewNullCol)
{
this.Parent = NewParent;
this.State = new byte[5, 5];
this.Move = NewMove;
this.ParentMove = ParentMove;
this.Depth = NewDepth;
this.NullRow = NewNullRow;
this.NullCol = NewNullCol;
this.Childs = new List<int>();
}
}
class StateTree : List<StateNode>
{
public static long MakedNodes;
public static long CheckedNodes;
public static byte MaxDepth;
public List<int> Successor1(int StateIndex)
{
List<int> RetNodes = new List<int>();
StateNode NewState = new StateNode();
//Up
if (this[StateIndex].NullRow + 1 <= 3 && this[StateIndex].ParentMove != Direction.Up)
{
NewState = ChangeItemState(this[StateIndex], StateIndex, Direction.Up, Direction.Down, Convert.ToByte(this[StateIndex].Depth + 1), this[StateIndex].NullRow, this[StateIndex].NullCol, Convert.ToByte(this[StateIndex].NullRow + 1), this[StateIndex].NullCol);
this.Add(NewState);
RetNodes.Add(this.Count - 1);
StateTree.MakedNodes++;
this[StateIndex].Childs.Add(this.Count - 1);
if (NewState.Depth > StateTree.MaxDepth)
StateTree.MaxDepth = NewState.Depth;
}
//Down
//Left
//Right
return RetNodes;
}
}
5 ответов
this[StateIndex]
использует свойство индексатора текущего класса. Свойство indexer - это то, что позволяет вам получить доступ к элементу в объекте коллекции или списка, как если бы это был массив. Например:
List<string> strings = new List<string>();
strings.Add("Item 1");
strings.Add("Item 2");
strings.Add("Item 3");
string x = strings[0]; // Returns the first item in the list ("Item 1")
Однако, когда вы хотите получить доступ к свойству indexer вашего собственного класса, вы должны предварять его this
ключевое слово. Вы заметите, что в вашем примере StateTree
Класс не реализует свойство индексатора, так что это может добавить к вашей путанице. Причина этого в том, что StateTree
наследуется от List<StateNode>
который реализует свойство индексатора.
Но не запутайтесь между классами со свойствами индексатора и массивами. Массивы - это совсем другое, хотя синтаксис похож. Массив - это список объектов, к которым можно получить доступ по индексу. Свойство indexer - это безымянное свойство одного объекта, который действует как массив. Так, например, List<string>
имеет свойство indexer, поэтому вы можете получить доступ к содержащимся в нем элементам, используя тот же синтаксис, что и индекс массива (как показано в приведенном выше примере). Тем не менее, вы все равно можете сделать массив List<string>
объекты. Так, например:
List<string> strings1 = new List<string>();
strings1.Add("Item 1.1");
strings1.Add("Item 1.2");
List<string> strings2 = new List<string>();
strings2.Add("Item 2.1");
strings2.Add("Item 2.2");
List<string>[] stringsArray = new List<string>[] { strings1, strings2 };
object result;
result = stringsArray[0]; // Returns strings1
result = stringsArray[0][1]; // Returns "Item 1.2"
result = stringsArray[1][0]; // Returns "Item 2.1"
Так далеко как StateNode
Конечно, в этом нет ничего плохого с технической точки зрения, и нет ничего необычного в том, чтобы иметь конструктор, который инициализирует все значения полей, но всегда лучше использовать свойства вместо открытых полей.
В вашем конкретном случае это просто доступ к элементу, так как он используется внутри класса, производного от List<T>
Но это также может быть индексатор, который позволяет индексировать доступ к вашему объекту класса.
Например, объявите класс следующим образом:
public class ListWrapper
{
private List<int> list = ...
public int this[int index]
{
return list[index];
}
}
и после использования это как
var lw = new ListWrapper();
//fill it with data
int a = lw[2]; //ACCESS WITH INDEX EVEN IF THE TYPE IS NOT COLLECTION BY ITSELF
Его Indexed Properties
в C# .net .
Вы можете проверить учебник: http://msdn.microsoft.com/en-us/library/aa288464(v=vs.71).aspx проверить здесь
this[StateIndex]
указывает на элемент в классе. Так как StateTree
наследует от List<T>
, у вас есть коллекция, которая доступна по индексу (в данном случае this[N]
где N
это индекс элемента.
Это [StateIndex], как вы даете класс и индексированное свойство, например
public class IndexedClass
{
private List<String> _content;
public IndexedClass()
{
_content = new List<String>();
}
public Add(String argValue)
{
_content.Add(argValue);
}
public string this[int index]
{
get
{
return _content[index];
}
set
{
_content[Index] = value;
}
}
}
так что теперь вы можете сделать
IndexedClass myIndex = new IndexedClass();
myIndex.Add("Fred");
Console.Writeline(myIndex[0]);
myIndex[0] = "Bill";
Console.Writeline(myIndex[0]);
Что касается statenode, если он локальный по отношению к классу (помощник), то вы можете поспорить, что все в порядке, хотя мне это не нравится, еще десять минут работы можно сделать правильно. Если это публично в сборке, то, по моему мнению, это не прилично. Но это мнение.