Как вы храните ссылку на свойство в C #? - PullRequest
3 голосов
/ 16 июля 2010

Я создаю игру и сейчас работаю над системой инвентаризации для нее. У меня есть класс для представления игрока, который выглядит следующим образом:

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

Оружие, Щит и т. Д. Являются подклассами общего класса предметов:

class Item {
    //...
}

class Weapon : Item {
    //...
}

Есть подклассы оружия и т. Д., Но это не важно.

В любом случае, я создаю UserControl для отображения / изменения содержимого данного слота инвентаря. Тем не менее, я не уверен, как именно это сделать. В C ++ я бы использовал что-то вроде:

new InventorySlot(&(player.WeaponSlot));

Но я не могу сделать это в C #.

Я обнаружил структуру TypedReference, но она не работает, поскольку вам не разрешено создавать поле с одной из этих структур, поэтому я не смог сохранить его для использования в дальнейшем в элементе управления.

Является ли рефлексия единственным путем, или есть какое-то другое средство, о котором я не знаю?

РЕДАКТИРОВАТЬ ----

Для справки, вот что я сделал:

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();
    }
    //...
}

И это инициализируется так:

new InventorySlot(player, "WeaponSlot");

Кроме того, что касается производительности, я не слишком обеспокоен этим. Это не игра в реальном времени, поэтому мне нужно только обновить экран в ответ на действия игрока. :)

Ответы [ 6 ]

4 голосов
/ 16 июля 2010

Я создаю UserControl для отображать / изменять содержимое данного слот для инвентаря. Однако я не уверен как именно это сделать. В C ++ я будет использовать что-то вроде

По умолчанию работает так, как вы хотите. Ключевое слово ref также не нужно.

3 голосов
/ 16 июля 2010

По сути, вы создаете браузер свойств. Взгляните на элемент управления PropertyGrid в Windows Forms (прочитайте документацию, чтобы узнать, как она работает, и / или используйте Reflector для чтения кода).

Короткий ответ - просто использовать отражение. Сохраняя PropertyDescriptor, вы можете получить и установить значение элемента свойства для данного экземпляра объекта.

1 голос
/ 21 июля 2010

Это стандартное поведение afaik

0 голосов
/ 21 июля 2010

Если вы действительно хотите ссылку, вы можете использовать поля вместо. На них может ссылаться ref.

0 голосов
/ 16 июля 2010

Вы можете клонировать объект для достижения того, что вы хотите:

public class Weapon : ICloneable
{
    public string Name;

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

Вы можете сделать что-то подобное, чтобы получить копию этого объекта со всеми внутренними значениями:

Weapon w1 = new Weapon();
Weapon w2 = w1.Clone()
0 голосов
/ 16 июля 2010

Каждый тип объекта class является ссылкой в ​​c #. Типы значений объявляются с struct.

Так, например:

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

Если вам нужен параметр ввода / вывода для функции, вы можете использовать ref. Если вам нужен выходной параметр, вы можете использовать out. Если вы просто передаете ссылку на объект типа class, вы можете просто передать его и изменить сам объект класса.

...