- Home /
How to read properties from an arraylist of objects C#
I'm quit new to working with objects in c# and don't know how to properly read values. I have a script that adds a bow object to a static array list in another scrip, but when I try to pull values from that arraylist, I get error CS1061.
This is my bow script:
using UnityEngine;
using System.Collections;
public class bow : MonoBehaviour {
public float damage;
public float firerate;
public float accuracy;
public string description;
public string name;
}
This is the script that assigns the bow to the arraylist:
bow coolbow = new bow ();
coolbow.damage = damage;
coolbow.firerate = firerate;
coolbow.accuracy = accuracy;
coolbow.description = description;
coolbow.name = name;
inventory.items.Add (coolbow);
And this is the inventory script:
using UnityEngine;
using System.Collections;
public class inventory : MonoBehaviour {
public static ArrayList items = new ArrayList();
void Update () {
if(items.Count > 0){
Debug.Log("" + items[0].damage);
}
}
}
Judging by the error you get, what ever is in cell 0 of the ArrayList, doesn't have a member called "damage".
What happens if you just do:
Debug.Log("" + items[0]);
?
@W1k3 Have you tried using List ins$$anonymous$$d of ArrayList?
Unless you have something forcing you to use ArrayList you should use a List ins$$anonymous$$d. ArrayList is only included in C# for backwards compatibility.
Answer by Kiwasi · Jul 10, 2014 at 11:48 PM
You are using a non generic function. Therefore items[0] is an object. To get it to a bow you need to use casting as follows
// If you are sure its a bow
((bow)item[0]).damage;
// Safe casting is slower, but won't throw a runtime error if it is not a bow
(item[0] as bow).damage;
I would suggest using the generic version List. Its faster and simpler to code.
To @Bored$$anonymous$$ormon point, ArrayLists as you can see from the example above require casting. There are inherit performance issues being introduced just from the point of casting, boxing and unboxing, particularly often can suck the life out of what your doing. Using generics introduces type safety(it is what it is) and better readability for the future.
Answer by gjf · Jul 11, 2014 at 09:55 AM
you'll likely be adding other inventory types too. here's an example of how you might approach it:
using UnityEngine;
using System;
using System.Collections.Generic;
public class InventoryItem
{
public string Name;
public string Description;
public Type ItemType;
}
public class Arrow : InventoryItem
{
public float Speed;
public Arrow()
{
ItemType = typeof (Arrow);
}
}
public class Bow : InventoryItem
{
public float Damage;
public float FireRate;
public float Accuracy;
public Bow()
{
ItemType = typeof (Bow);
}
}
public class InventoryExample : MonoBehaviour
{
public List<InventoryItem> Inventory = new List<InventoryItem>();
public void Awake()
{
var coolbow = new Bow { Name = "Dummy", Description = "Dummy item description", Damage = 2.0f, FireRate = 1.0f, Accuracy = 50.0f };
Inventory.Add(coolbow);
var arrow = new Arrow { Name = "Arrow", Speed = 10.0f };
Inventory.Add(arrow);
}
public void Update()
{
foreach (var inventoryItem in Inventory)
{
if (inventoryItem.ItemType == typeof (Bow))
{
var bow = (Bow) inventoryItem;
Debug.Log("Bow damage is " + bow.Damage);
}
if (inventoryItem.ItemType == typeof (Arrow))
{
var arrow = (Arrow) inventoryItem;
Debug.Log("Arrow speed is " + arrow.Speed);
}
}
}
}
put everything that's common to all inventory items in the InventoryItem
class, and specific things in each class (i've created Bow
& Arrow
to illustrate this) and how you'd access each (casting to the correct type as suggested by BoredMormon)
I was going to suggest something like that, but it was a bit much to write out.
Never seen anyone cache the type of an object before, is it faster then just getting the runtime type using reflection?
i've used it to illustrate something before so wasn't a huge effort to cut&paste then tweak a little ;)
re: the caching - i don't imagine that doing it at runtime would be faster although ymmv
Answer by Nick4 · Jul 10, 2014 at 08:45 PM
You can't create an instance of an object that inherits Monobehaviour using the "new" key. So your bow class simply can't inherit Monobehaviour.
I changed public class bow : $$anonymous$$onoBehaviour to public class bow and it didn't make a difference.