- Home /
C# - Class (Instance/object) to List
I have a instance CharObject, which holds several instances of Stat. Is there a way for me to dynamically generate a List from an instance of CharObject? I need to get all the instances of Stat into a List so that I can send them to and from the database. I use a series of text splits and such down the way which all function properly with arrays.
I just need to be able to go ham on them somewhere down the line with text splits and converting them to and from arrays. Need filter power basically. Thanks.
Note: The application requires this flexibility, non-flexible arrays or objects[] will not do.
CharObject.cs
using UnityEngine;
using System.Collections;
using System;
public class CharObject
{
private Stat _hp = new Stat();
private Stat _Src = new Stat();
private Stat _Sta = new Stat();
private Stat _Spd = new Stat();
public Stat hp
{
set { _hp = value; }
get { return _hp; }
}
public Stat Src
{
set { _Src = value; }
get { return _Src; }
}
public Stat Sta
{
set { _Sta = value; }
get { return _Sta; }
}
public Stat Spd
{
set { _Spd = value; }
get { return _Spd; }
}
}
Stat.cs
using UnityEngine;
using System.Collections;
public class Stat
{
private int _current;
private int _max;
private int _temp;
public int current
{
set { _current = value; }
get { return _current; }
}
public int max
{
set { _max = value; }
get { return _max; }
}
public int temp
{
set { _temp = value; }
get { return _temp; }
}
}
How about collection classes from the C# native library? You might want to consider LinkedList or Dictionary. Both are generic (meaning that you can use them to store a custom type), and the latter is compatible with Unity's serialization.
Answer by Bunny83 · May 06, 2012 at 12:32 PM
Like @jacek-wesolowski mentioned in the comment above a generic .NET / Mono List would do the job ;)
You need of course to include this namespace:
using System.Collections.Generics;
Then you can use the list like that:
private List<CharObject> _Chars = new List<CharObject>();
// [...]
// Add an object to the list:
CharObject char = new CharObject();
_Char.Add(char);
edit
Sorry i just realized you want the Stats into an array... hold on...
Ok just add this property to your CharObject class:
public Dictionary<string,Stat> AllStats
{
get
{
var result = new Dictionary<string,Stat>();
System.Type T = GetType();
FieldInfo[] fields = T.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var f in fields)
{
if (f.FieldType == typeof(Stat))
{
Stat S = (Stat)f.GetValue(this);
result.Add(f.Name,S);
}
}
return result;
}
}
It will return a dictionary that contains all private fieldnames of type Stat along with the current value (the Stat object).
You need those additional namespaces:
using System.Collections.Generics;
using System.Reflection;
This is my test:
CharObject O = new CharObject();
O.hp.current = 100;
foreach (var S in O.AllStats)
{
Debug.Log("Stat: " + S.Key + " = "+ S.Value.current);
}
which prints 4 lines:
Stat: _hp = 100
Stat: _Src = 0
Stat: _Sta = 0
Stat: _Spd = 0
Thanks a lot, more than I could ask for. Question though.
If I where to augment a value in the dictionary, say in the foreach I put "S.Value.current = 100;", would that actually set the values in CharObject? I tried it, and it looks like it is O.O Which is awesome but unexpected.
Your Stat type is a class and therefore a reference type. It doesn't matter how often you copy or pass the reference to other functions, it still points to the same class instance.
structs on the other hand are value types so they are treated like an int or float. If you assign a struct variable to another struct variable the actual content get copied. That's the main difference between structs and classes. ;)
See struct($$anonymous$$SDN) or this introduction into structs
A typical example for a struct in the Unity3D API is Vector3 or RaycastHit
Very very good to know. So used to typing dynamically. Hope you don't $$anonymous$$d another question @Bunny83
Noticed: BindingFlags.Instance & typeof(Stat)
Some of the "Stats" in my charObject aren't instances of "Stat." Some are just plain strings or integers. Would it be possible to add those to the dictionary just as easily?
If not I guess I could just make them an instance of Stat and add their value to Stat.current and give Stat a string element for string based values.
Thanks.
Well, if you really wanted to you could make implicit casts from string and int to 'Stat'. That would allow you to add them to your dictionary easily. Just keep in $$anonymous$$d that what you get back out will be just Stat objects, not strings or integers. You'll need to have appropriate members, of course.
That's not possible with a strongly typed dictionary. You can use a dynamic typed dictionary. There you can store what ever you like as long as you consider the correct type when you want to access it again.
Note that int is and string behaves like a value type. So when you use GetValue on a property of type int, it will return the value. In the case of a reference type the value is the reference, but for value types it's just a copy of the value itself. So changes to that copy won't affect the original value.