Mark Aven
Mark Aven

Reputation: 365

How do I reference a value within a class in c#?

This is gonna sound like a really stupid question, but I have a simple data structure that looks like this in my game:

public class MG_GameData
{
    public List<SceneObject> SceneList = new List<SceneObject>();
    public RPG_Data rpg_Data = new RPG_Data ();
}

public class SceneObject
{
    public string SceneName;
    public List<VarObject> VarList = new List<VarObject> ();
    public List<O_Object> O_ObjectList = new List<O_Object>();
}

public class VarObject
{
    public enum VarType { Bool, String, Number }
    public VarType varType;
    public string VarName;
    public object VarValue;
}

public class O_Object
{
    public string O_Object_gameObjectName;
    public Vector3 storedPosition;
    public Vector3 storedRotation;
    public int interpreterCurIndex;
    public O_Lists.O_Lists_Base o_Lists_Base;
    public O_Base.Control control;
}

When I create the object, I create it as a static object named mg_GameData using MG_GameData mg_GameData = new MG_GameData();

Now, in my program, I can access it in this manner:

MG_Data.mg_GameData.SceneList[curSceneIndex].VarList[curVarValueIndex].VarValue = 5; //for example.

This may sound noobish, but I don't know how to create a proper reference to the VarList within my methods, so my methods are starting to look completely cluttered.

VarList varList = MG_Data.mg_GameData.SceneList[curSceneIndex.VarList; ??

But then when I change the data using varList will it change the data within MG_Data.mg_GameData.SceneList[curSceneIndex.VarList?

Upvotes: 0

Views: 106

Answers (1)

Dour High Arch
Dour High Arch

Reputation: 21712

You haven't explained what your code is supposed to do, and the names are rather vague. Those are both problems, but already there are several yellow cards in your code:

MG_GameData mg_GameData = new MG_GameData();

What is “MG_GameData” supposed to mean? You're using it both for a class and instance name, so it can't be very descriptive. Is “MG” supposed to be an abbreviation? You should be using namespaces for that.

I create it as a static object

Why are you doing that? That's going to make it really difficult to test your class. You should not be using static instances unless you absolutely have to.

public class VarObject
{
public enum VarType { Bool, String, Number }
public VarType varType;
public string VarName;
public object VarValue;
}

Uh oh, this looks like the Inner-Platform antipattern, where you try to duplicate built-in language features like inheritance and overloading inside your classes instead of using the language to do them. What's a VarObject? What's it do? You should implement classes that only contain and do what you need.

All your classes suffer from the Primitive Obsession antipattern, where you create a bag of primitive types, like strings and integers, and expect the consumers of your class to do all the low-level fiddling to represent state changes and behaviors. Only madness lies down that path. You should be creating classes to describe the model and behavior, not exposing primitive types to every consumer of your class.

MG_Data.mg_GameData.SceneList[curSceneIndex].VarList[curVarValueIndex].VarValue = 5; //for example

This violates the Law of Demeter, which basically says the consumer of your class must not know how class properties are implemented. Not only must the consumer of mg_GameData know that SceneList is implemented as a List<VarObject>, but the consumer must do all the creation, updating, and management of every property of every class. None of your classes enforce any constraints or implement any behaviors; they're all pretty much useless!

@Jinal is right; you need to abstract your data into classes that implement your game behavior and change state only through class methods. Your code should look more like this:

var playerWorld = new GameWorld( new Scene[]
    { new SceneMountain(), new SceneMountain(), ...
      new SceneMountain(), new SceneGrassland(new Monster("Grue", CR: 1, HP:15, AC: 5, THAC0:10, Damage: new DamagerInnate(dice:1))), ...
      ...
    });
var player = new Hero("Hiro", CR: 1, HP: 6, AC:2, THAC0: 9,
    Damage: new DamagerWeapon("longsword", dice: 2, SpecialRules: Rule.Edged | Rule.ColdSteel));
playerWorld.Place(player, new Location(4, 5));
foreach (var monster in playerWorld.Monsters)
    monster.MoveToward(player.Location);

Upvotes: 2

Related Questions