1

I've got a small project where I would like to avoid creating a setter for each integer. So I'm thinking if it's even possible.

So I would like to set an amount of
player.setResource(player.money, 100);,
player.setResource(player.coal, 20);,
etc.

I'm not sure first of all if it's possible, and second of all how to write a function itself.

public void setResource(int resource, int amount)
{
        ???
}
idzczakp
  • 313
  • 1
  • 2
  • 9

5 Answers5

1

Use an enum for this. Define an enum in your project like so

public enum ResourceType { Coal = 0, Money = 1, Health = 2 }

Now, you can add a switch case in your setResource function to check what enum you've passed, and set the corresponding value. This is however assuming all your values are integers. you can make a separate one for floats, or just use floats for everything, upto you.

This will be your new SetResource Function, assuming you have a reference to your player.

public void setResource(ResourceType resource, int amount)
{
    switch(resource)
    {
         case ResourceType.Money:
                 player.money = amount;
                 break;

        case ResourceType.Coal:
                player.coal = amount;
                break;


    }
}
varunkaustubh
  • 301
  • 1
  • 7
1

You can use an Enum to define the resources types and a Dictionary to store the values of each resource. Here's an example:

public enum ResourceType
{
    Coal,
    Money
}

private Dictionary<ResourceType, int> _resources = new Dictionary<ResourceType, int>();

public void SetResource(ResourceType resourceType, int value)
{
    _resources[resourceType] = value;
}

public int GetResource(ResourceType resourceType, int defaultValue = 0)
{
    if (_resources.TryGetValue(resourceType, out var value))
        return value;
    else
        return defaultValue;
}
Galman33
  • 154
  • 3
0
public class Player
{
    public int money { get; set; }
    public int coal { get; set; }

    public void setResource(string resource, int amount)
    {
        this.GetType().GetProperty(resource).SetValue(this, amount);
    }
}

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        Player player = new Player();
        player.setResource(nameof(player.coal), 4);
    }
}
Ahmed Alayat
  • 172
  • 1
  • 1
  • 11
0

In your method, the target is not passed, the value of the integer is assigned to a local variable resource that only exists within the method.money and coal are not affected.

You need to pass the address of those data.

public void setResource(ref int resource, int amout)
{
    resource = amount;
}

player.setResource(ref player.coal, 100);

If nothing else happens in the method, a get/set property would do the same.

Everts
  • 10,408
  • 2
  • 34
  • 45
  • 1
    This is almost perfect, just flip it around so that it's the same as the question, in terms of `public void setResource(ref int resource, int amount)` in the method call, and is therefore in the same order in the method implementation `{ resource = amount }`. – Confused Nov 07 '21 at 12:36
  • 1
    I did the edit. Its a personal habit to put ref parameters at the end of the list. Dunno why. – Everts Nov 07 '21 at 13:07
  • Well .. but then why not just do `resource = amount` right where you would use that method in the first place? I think OP is really rather after the `enum` solution via dictionary mentioned in [this answer](https://stackoverflow.com/a/69862482/7111561) – derHugo Nov 07 '21 at 16:47
  • 1
    Mostly because you would not have to add a new enum entry for each resource. Overall i dont see the purpose, i just answered the question. One could say it allows the members to be private just to be indirectly exposed via the method anyway. At the end i mentioned this does nothing more than a get/set property. – Everts Nov 08 '21 at 17:45
  • I think the OP was merely trying to understand the method (pun!) of doing things with methods rather than Properties, and created the simplest example he could, as a means to ask the question, in the hope he could see ways to do it, then apply anything that made sense to anything they're considering actually doing. – Confused Nov 09 '21 at 10:41
  • OP explicitly states "to avoid creating a setter for each integer". This solution not only fails to achieve that goal, it in fact exacerbates the problem with a code explosion. – Immersive Nov 10 '21 at 05:34
  • @Immersive could you elaborate on how this fails on all levels of requirement? – Everts Nov 11 '21 at 07:07
  • in the case of two resources, 'coal' and 'lumber', instead of ```player.coal = 100; player.lumber = 50;```, your solution would require OP to use ```player.setResource(ref player.coal, 100); player.setResource(ref player.lumber, 50);```. There is no simplification of value storage, and significant expansion on get/set code. – Immersive Nov 12 '21 at 09:26
  • The core issue is your code still requires the declaration and instantiation of unique resource fields. – Immersive Nov 12 '21 at 09:30
  • Please, have a look at the question and how OP is willing to use. Regardless of whether it makes sense this is how he wants. I did mention this is just like get/set. It feels you just went on without reading through the question nor the answer. – Everts Nov 12 '21 at 15:36
-2

There are multiple ways how you could do this. I often use this aproach for quick prototyping.

First you create two variables for the data you want to assing, then you create a Setter function and with this you can set variables through other scripts.

int value 1;
int value 2;

public void SetData(int value1, int value2)
{
   this.value1 = value1;
   this.value2 = value2;
}

The same aproach can be used for other data types, you just need to create the variables.

Filip Studený
  • 470
  • 1
  • 3
  • 11
  • That would mean you need to always set the reo even though you needed only one of them. And it needs extra parameters any time you need a new data. – Everts Nov 06 '21 at 12:28