Asimm Asimm - 1 year ago 96
C# Question

Store reference of a value type variable C#

I'm trying to create status effect's for my game those are things that affect your player's statistics over time for example. However I'm having trouble with remembering the passed variable i.e the one that should be modified. Let's say you have some status effect that reduces your Health by 10 % for 10 seconds the way I do it is by instantiating a new class passing some parameters in along with the variable that needs to be modified in this case player's health, but the problem is that once the constructor is gone the reference is being broken between those 2 and from then on I just edit some variable that is never being used.

Here's how i instantiate a Status Effect

/// <summary>
/// Creates a status effect which ticks at specified period of time without any condition.
/// </summary>
public StatusEffect(float increase, EffectIncreaseType increaseType, float timeOfStatusEffect, float tickTime)
this.increase = increase;
this.endTimeOfStatusEffect = Time.time + timeOfStatusEffect;
this.tickTime = tickTime;
increaseCalculator = increaseType == EffectIncreaseType.Percentage ? increaseCalculator = (a) => (int)(increase / 100f * a) : increaseCalculator = (a) => (int)increase;

And here's how I use it now

public bool TryTrigger(ref int affectedProperty)
if (condition.Invoke(affectedProperty))
affectedProperty += increaseCalculator.Invoke(affectedProperty);
return condition.Invoke(affectedProperty);

This is not what i want first of all it requires a field to be passed to the method
not a property second of all you are not supposed to know what variable is required all the time you should just passed it in the start and then try triggering that with the class itself working with that variable in the back stage. Is that possible ? Is there a better approach for making Status Effects (DoT,HoT) ? Also I will like to make this work for instant status change for example decrease your health by 30 % for 1 minute but I'm not sure if my current setup is good for that.

Answer Source

There's no way to store a "ref" to a variable in .NET; that's deliberate. It eliminates the class of bugs common in C / C++, where you store a ref to a variable past its lifetime and bad things happen.

The way to do what you want is instead, pass in an Action<T> that sets the variable (or property) you want to change, and then when you want to change it, you invoke the action.

How then does that solve the problem? Because C# makes sure that the variable captured by the delegate is always long-lived.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download