21

Is there an easy way to create something like the following JS code:

var players = [
    {name:"Joe",score:25,color:"red",attribs:[0,1,2,3,4]},
    {name:"Jenny",score:1,color:"black",attribs:[4,3,2,1,0]}
];

in C# (for Unity 3d)?

I've already looked at List, Dictionary and ArrayList, but everything seam so ... inflexible and overcomplicated...

The main objective here is to have something flexible, that can be access from many other places w/o the need to remember array indexes, variable types etc. Probably can't be done in C#... But something that is fairly close should be enough. ArrayList maybe...?

Thank you.

user3789335
  • 235
  • 1
  • 2
  • 5
  • Take a look at JSON parsers, I personally am very fond of JsonFX. – This company is turning evil. Oct 22 '14 at 01:05
  • take a look at this http://stackoverflow.com/questions/1056121/how-to-create-json-string-in-c-sharp – blackmind Oct 22 '14 at 01:20
  • c# is a type safe language, I would not call that inflexible or complicated, just a different language – sa_ddam213 Oct 22 '14 at 01:20
  • 3
    just to be clear, this piece of JavaScipt is an array of objects, that concept is directly transferable to C#. Are you able to add the C# code that you have tried and what problems you having with it i.e. why is it inflexible and overcomplicated, is it lacking some functionality that you need. The issue you may be having is to do with a weakly typed language vs a strongly typed one – OJay Oct 22 '14 at 01:20
  • THANK YOU GUYS FOR ALL YOUR ANSWERS. – user3789335 Oct 22 '14 at 02:05

3 Answers3

24

This JavaScript being an Array of objects is directly transferable to C#, and you have multiple ways to do it and multiple collection classes to use (unlike JavaScript which only has one collection class)

It can almost be written verbatim in C# and is perfectly valid (Using Anonymous Types):

var players = new [] {
    new  {name = "Joe",score = 25, color = "red", attribs = new int[]{ 0,1,2,3,4}},
    new  {name = "Jenny",score = 1, color = "black", attribs = new int[]{4,3,2,1,0}}
};

But I'm not sure if this is going to achieve what you want (Functionality wise)

IMO creating a typed object would be a better approach (I would consider this to be a better approach in both C# and JavaScript), so I would approach it more like this (JavaScript):

function Player(name,score,color,attribs)
{
    this.name = name;
    this.score = score;
    this.color = color;
    this.attribs = attribs;
}

var players = [
    new Player("Joe", 25, "red", [0, 1, 2, 3, 4]),
    new Player("Jenny",1,"black", [4, 3, 2, 1, 0])
];

and the same thing in C#:

public class Player
{
    public string name;
    public int score;
    public string color;
    public int[] attribs;
}


Player[] players = new Player[]{
         new Player(){ name = "Joe", score = 25, color = "red", attribs = new int[]{0,1,2,3,4} },
         new Player(){ name = "Jenny", score = 1, color = "black", attribs = new int[]{4,3,2,1,0} },
};

or to get a lot more flexibility you can use them in a List like:

 List<Player> players = new List<Player>(){
             new Player(){ name = "Joe", score = 25, color = "red", attribs = new int[]{0,1,2,3,4} },
             new Player(){ name = "Jenny", score = 1, color = "black", attribs = new int[]{4,3,2,1,0} },
    };
OJay
  • 4,763
  • 3
  • 26
  • 47
  • That looks fantastic. Only problem is that I need to make it "global" but Unity throws 'error CS0825: The contextual keyword `var' may only appear within a local variable declaration'. – user3789335 Oct 22 '14 at 01:41
  • var is only valid in method scope and Globals are evil. Without knowing your code, wouldn't you have something like a Game object that has a players collection? or something similar. If you must have the players collection global, you won't be able to use implicit typing (i.e. can't use `var`, you will have to use a type, try the typed options meaning `Player[]`) – OJay Oct 22 '14 at 01:57
  • Thank you OJay. That list thingy was exactly what I needed. :D – user3789335 Oct 22 '14 at 02:04
4

Could you make a Player model (class) with the Name, Score, Color, Attribs properties and store each Player in memory in a List<Player>:

public class Player
{
    public string Name { get; set; }
    public int Score { get; set; }
    public string Color { get; set; }
    public int[] Attribs { get; set; }
}

...

List<Player> myPlayers = new List<Player>();
Player joe = new Player();
joe.Name = "Joe";
joe.Score = 25;
joe.Color = "red";
joe.Attribs = new int[] { 0, 1, 2, 3, 4 };;
myPlayers.Add(joe);

Using System.Linq you could query the List<Player> for specific players Eg:

Player player = myPlayers.SingleOrDefault(p => p.Name == "Joe");

Extra credit - always test that player is not default before trying to use it:

if (player != default(Player))
{
    // do something with joe
}
logikal
  • 1,123
  • 13
  • 26
3

More or less match for syntax would be anonymous types:

var players = new[]{
    new {name = "Joe", score = 25, color = "red", attribs = new[]{0,1,2,3,4}},
    new {name = "Jenny", score = 1, color = "black", attribs = new []{4,3,2,1,0}}
};

but it have very different meaning than JavaScript (array of immutable strongly typed objects in C# vs. dictionary of duck typed object in JavaScript).

You may want to look into using dynamic and ExpandoObject which exists to support languages like JavaScript in .Net if they are present in Unity3d.

    dynamic person = new System.Dynamic.ExpandoObject();
    person.Name = "John Smith";
    person.Age = 33;

Note that C# is strongly typed language and it may be better to change way of thinking to match the language. Staying with JavaScript is reasonable option if you can't get away from duck typed languages.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179