Question

i have recently stumbled upon a project(8-puzzle solver using A* alg) in which some codes are weird to me , because i have never seen the likes of it before .

what does this line mean ? what is this ?!

this[StateIndex]

whats this notation ? i cant undersand it at all ! i posted a sample of the class so that you can see it almost all together . and one more question , is it not wrong to have a class implemented like StateNode? it used only a constructor to initialize its fields , and yet worst, declared them all public ! should he/she not have implemented Propertise for this task?

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;
}
}
Was it helpful?

Solution

this[StateIndex] is using the current class' indexer property. The indexer property is what allows you to access an element in a collection or list object as if it was an array. For instance:

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")

When you want to access the indexer property of your own class, however, you have to preface it with the this keyword. You'll notice that in your example, the StateTree class doesn't implement an indexer property, so that may be adding to your confusion. The reason it works is because StateTree inherits from List<StateNode> which does implement an indexer property.

But don't get confused between classes with indexer properties and arrays. Arrays are a completely different thing, though the syntax is similar. An array is a list of objects which can be accessed by an index. An indexer property is an unnamed property of a single object that acts as an array. So for instance, List<string> has an indexer property, so you can access the items it contains using the same syntax as an array index (as shown in the above example). However, you can still make an array of List<string> objects. So for instance:

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"

As far as StateNode goes, there's nothing technically wrong with it, and it's not unusual to have a constructor that initializes all the field values, but it's always better to use properties instead of public fields.

OTHER TIPS

In your concrete case it's just access to the element, as it used inside the class that is derived from the List<T>

But it can be also indexer which enables index acces to your class object.

For example declare class like this:

public class ListWrapper
{
    private List<int> list = ...

    public int this[int index]
    {
        return list[index];
    }
}

and after use it like

var lw = new ListWrapper(); 
//fill it with data 

int a = lw[2]; //ACCESS WITH INDEX EVEN IF THE TYPE IS NOT COLLECTION BY ITSELF

its Indexed Properties in C# .net .

you can check Tutorial : http://msdn.microsoft.com/en-us/library/aa288464(v=vs.71).aspx check here

this[StateIndex] is pointing to an element within the class. Because StateTree inherits from a List<T>, you have a collection that's accessible by index (in this case this[N] where N is the element's index.

this[StateIndex] is how you give a class and indexed property e.g

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;
     }
  }
}

so now you can do

IndexedClass myIndex = new IndexedClass();
myIndex.Add("Fred");
Console.Writeline(myIndex[0]);
myIndex[0] = "Bill";
Console.Writeline(myIndex[0]);

As for statenode if it's local to the class (a helper) then you could argue it as okay, I don't like it though, another ten minutes work it could be done properly. If it's public in the assembly, then it's not accpetable in my opinion. But that is an opinion.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top