C# finite state machine — declaring a variable inside that class

When creating the finite machine:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class State
{

    public abstract State RunCurrentState();
    
}

In this case, I created a method with the class “State” in the class “State”
I don’t really understand why you can declare a method or variable with the same class when declaring that class. Won’t that create a recursion loop? Thanks

The answer to your question depends a lot on the context , let’s start with the easy answers first :

  • The return type of a method isn’t really bound by where it is located , that method can be placed where ever you want as long a it’s valid syntax , i dunno where you got that impression or what hinted at it , but a method is just a chunk of code that takes parameters (or not) and returns a value (or not if it’s void) (i’m simplifying here but that’s the essence of it)

Now for the “variable” (ill call it a field to be more specific)
The context here is important , objects in C# can be either classes or structs , classes are referred to reference types while structs as value types.

When you are using a class object , you’re not actually operating on the “chunk of memory” directly , you’re basically operating on a handle (or a pointer if you’re familiar with those) , you can imagine your object as an int indicating where the actual object lies , whenever you’re passing the object around you’re basically just passing THAT int to reference where the object is located (hence the name reference type).

State state = new State(); // what you type
int pointerToNewlyCreatedState = new State(); // what you can imagine it as

All of that is to explain that whether your class has 0 fields or hundreds of fields , it will always be passed around as an int , so the content of the class irrelevant, hence when you do something like

class State 
{
    public State internalField;
    // todo : rest of the class
}

you can see it as

class State 
{
    public int pointerToInternalField; // no matter how big the class is , at the end of the day it's pointed to by an "int"
    // todo : rest of the class
}

you can even do

class State 
{
   private int score;
   public State AddScoreAndReturnSelf()
   {
          score += 1;
          return this;  // imagine this as returning the address of the current object (the so called int)
   }
}

Now for the struct case , the description is accurate here , it’s a value type , so you’re operating on the value directly , there’s no “pointing” , what you see is what you get , hence since were dealing concrete values and with concrete sizes (and not with ints that point to stuff) , we cannot have a field contained in the same parent type.
Take this case

public struct MyStruct 
{
    public int id;
    public MyStruct  child;
}

What’s the size of this struct ? if you try to calculate it , you get the infinite loop that you mentioned since
size(MyStruct) = size(int) + size(MyStruct)
size(MyStruct) = size(int) + (size(int) + size(MyStruct))
size(MyStruct) = size(int) + (size(int) + (size(int) + size(MyStruct)) )
you get the point , we can’t even get the concrete size of this thing , so that struct wont compile (so in this case , you “recursion” concern is valid).

If this doesn’t help with clearing things up , i suggest looking up “reference type vs value type” and your search engine should take it from there , hope this helped.