views:

177

answers:

6

I'm creating a game, and am currently working on the Inventory system for it. I have a class to represent the player, which looks like this:

class Player {
    public Weapon WeaponSlot {get;set;}
    public Shield ShieldSlot {get;set;}
    //etc.
}

Weapon, Shield, etc are subclasses of a generic Item class:

class Item {
    //...
}

class Weapon : Item {
    //...
}

There are subclasses of Weapon, etc, but that's not important.

Anyway, I am creating a UserControl to display/modify the contents of a given inventory slot. However, I'm not sure exactly how to do that. In C++, I would use something like:

new InventorySlot(&(player.WeaponSlot));

But, I can't do that in C#.

I found the TypedReference struct, but that doesn't work since you are not allowed to make a field with one of those structs, so I couldn't store it for use later in the control.

Is reflection the only way to go, or is there some other facility that I'm not aware of?

EDIT ----

For reference, here's what I've done:

partial class InventorySlot : UserControl {
    PropertyInfo slot;
    object target;

    public InventorySlot(object target, string field) {

        slot = target.GetType().GetProperty(field);

        if (!slot.PropertyType.IsSubclassOf(typeof(Item)) && !slot.PropertyType.Equals(typeof(Item))) throw new //omitted for berevity

        this.target = target;

        InitializeComponent();
    }
    //...
}

And, it's initialized like this:

new InventorySlot(player, "WeaponSlot");

Also, regarding performance, I'm not too concerned about that. It's not a real-time game, so I only have to update the screen in response to player actions. :)

A: 

Every class type object is a reference in c#. Value types are declared with struct.

So for example:

Weapon w1 = new Weapon();
w2 = w1;//Does not make a copy just makes a second reference to what w1 is pointing to

If you need an input/output parameter to a function you can use ref. If you need an output parameter you can use out. If you are just passing a reference to an object that is of type class then you can just pass it and modify the class object itself.

Brian R. Bondy
+4  A: 

I am creating a UserControl to display/modify the contents of a given inventory slot. However, I'm not sure exactly how to do that. In C++, I would use something like

It works the way you want by default. "ref" keyword is not needed either.

kekekela
The problem is that the inventory slots are properties on an object, not objects themselves. I need(ed) a reference to the property itself, which is only possible with reflection. (which is the route I went)
Mike Caron
A: 

You could clone the object to achieve what you want:

public class Weapon : ICloneable
{
    public string Name;

    object ICloneable.Clone()
    {
        return this.Clone();
    }
    public Weapon Clone()
    {
        return (Weapon)this.MemberwiseClone();
    }
}

You can than do something like this to get a copy of that object with all the internal values:

Weapon w1 = new Weapon();
Weapon w2 = w1.Clone()
Børge
Scrap this.. :) This is how you could do it if you did not want to modify the actual object.
Børge
+3  A: 

Essentially what you are creating is a property browser. Have a look at Windows Forms' PropertyGrid control (read the docs to see how it works and/or use Reflector to read the code).

The short answer is to simply use reflection. By storing a PropertyDescriptor you can get and set the value of the property member given the object instance.

Tergiver
Sounds like this is the way to go... I thought there might be another way, but thanks
Mike Caron
It really is the way to go. Not only do you gain access to the property value, but also to any metadata it might have (i.e. Attributes).
Tergiver
+1  A: 

This is the default behavior afaik

marvelous marv
A: 

If you really want a reference, you can use fields instead. They can be referenced by ref.

leppie
And, how would I STORE this reference for later consumption?
Mike Caron