Как можно обновить значение ссылки внутри словаря? - PullRequest
0 голосов
/ 29 мая 2020

У меня есть куча частных переменных, которые мне нужно постоянно изменять во время выполнения. Мне нужно сохранить их конфиденциальность, поэтому метод publi c для обработки этого - очевидное решение, но наличие внутри него такого количества операторов If для проверки каждой переменной звучит как плохой вызов.

Я добавил их в частный словарь и создал метод, который ищет нужную переменную и изменяет ее, но есть проблема, я меняю ссылку в словаре, а не переменную. Есть идеи?

public enum MyEnum {Speed, Intelligence, Strength, Agility}
public class Player
        {
            private int playerSpeed = 1; //imagine a bunch more of this, not just one

            private Dictionary<MyEnum, int> MyDictionary = new Dictionary<MyEnum, int>();

            public void AnyMethod()
            {
                MyDictionary.Add(MyEnum.Speed, playerSpeed); //imagine a bunch more of this, not just one
            }

            public void ChangePlayerStat(MyEnum whatStatDoYouWantToChange, int howMuch)
            {
                if (MyDictionary.ContainsKey(whatStatDoYouWantToChange))
                {
                    MyDictionary[whatStatDoYouWantToChange] += howMuch;
                }
            }

            ChangePlayerStat(MyEnum.Speed, 99);
            Debug.Log(playerSpeed); // -> 1 and I want it to be 100

            //anybody knows if there's a way for this to work? ... Like using the ref keyword or something? idk

            //thank you :)


        }

Ответы [ 2 ]

0 голосов
/ 29 мая 2020

Итак, основная проблема здесь: int - это тип Value , а не ссылочный тип!

Таким образом, после добавления его в словарь вы, скорее всего, захотите получить только значение из словаря, а не из поля.

например,

Debug.Log(MyDictionary[MyEnum.Speed]);

вместо


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

public enum MyEnum {Speed, Intelligence, Strength, Agility}
public class Player
{
    // Use these ONLY as the initial value but later they have no function anymore!
    private int initialPlayerSpeed = 1;

    private Dictionary<MyEnum, int> MyDictionary = new Dictionary<MyEnum, int>();

    public void InitializeOrReset()
    {
        MyDictionary[MyEnum.Speed] = initialPlayerSpeed;
    }

    public bool ChangePlayerStat(MyEnum whatStatDoYouWantToChange, int howMuch)
    {
        // Note that "MyEnum.whatStatDoYouWantToChange" would not be valid c# here!

        if (MyDictionary.ContainsKey(whatStatDoYouWantToChange))
        {
            MyDictionary[whatStatDoYouWantToChange] += howMuch;
            return true;
        }

        Debug.LogWarning($"No Stat with key {whatStatDoYouWantToChange} exists in dictionary");
        return false;
    }

    public bool TryGetValue(MyEnum whatStatDoYouWantToGet, out int result)
    {
        result = int.MinValue;

        return MyDictionary.TryGetValue(whatStatDoYouWantToGet, out result);
    }
}

, а затем использовать его, например,

if(player.ChangePlayerStat(MyEnum.Speed, 99))
{
    Debug.Log("Successfully update stat MyEnum.Speed");
    if(player.TryGetValue(MyEnum.Speed, out var result))
    {
        Debug.Log($"=> New Value is {result}");
    }
}

Альтернатива использованию Метод getter будет свойством, упомянутым в Enigmativity (хотя это решение выдает исключения, если их ключ по какой-то причине не существует;))

0 голосов
/ 29 мая 2020

Все просто. Просто превратите свое поле playerSpeed в свойство, поддерживаемое словарем:

public class Player
{
    public Player()
    {
        this.playerSpeed = 1;
    }

    private int playerSpeed
    {
        get => MyDictionary[MyEnum.Speed];
        set => MyDictionary[MyEnum.Speed] = value;
    }

    private Dictionary<MyEnum, int> MyDictionary = new Dictionary<MyEnum, int>();

    public void ChangePlayerStat(MyEnum whatStatDoYouWantToChange, int howMuch)
    {
        if (MyDictionary.ContainsKey(whatStatDoYouWantToChange))
        {
            MyDictionary[whatStatDoYouWantToChange] += howMuch;
        }
    }

    public void Demo()
    {
        ChangePlayerStat(MyEnum.Speed, 99);
        Debug.Write(playerSpeed);
    }
}

Теперь попробуйте этот код:

var p = new Player();
p.Demo();

Я получаю 100.


Другой вариант, который вы можете рассмотреть, это:

public class Player
{
    private int playerSpeed = 1;
    private int playerIntelligence = 1;
    private int playerStrength = 1;
    private int playerAgility = 1;

    public void ChangePlayerStat(MyEnum whatStatDoYouWantToChange, int howMuch)
    {
        switch (whatStatDoYouWantToChange)
        {
            case MyEnum.Speed:
                playerSpeed += howMuch;
                break;
            case MyEnum.Intelligence:
                playerIntelligence += howMuch;
                break;
            case MyEnum.Strength:
                playerStrength += howMuch;
                break;
            case MyEnum.Agility:
                playerAgility += howMuch;
                break;
        }
    }

    public void Demo()
    {
        ChangePlayerStat(MyEnum.Speed, 99);
        Debug.Write(playerSpeed);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...