I'm looking for a way to attach listener to a C# variable, so that every time its updated or read, it will execute a function which will go on and process their own variables.
I know of the means described below but I'm looking for something that would work like the actualListener. Every single time someone asks this question they're re-refered to get/set.
Is there a way to attach an actual listener to a variable which would update the variable as well as invoke an Event? Nobody ever says it can't be done or that it will take major effort.

// Downside: If I have to do this for every variable, if I will have to change a little bit of set, I will have to repeat that action in every set
class getset
{
    int _myInt = 5;
    string _myText = "Donk";

    public int myInt
    {
        get => _myInt;
        set
        {
            _myInt = value;
            print($"React to some of this: {myInt}");
            // or PerformAction(myInt);
        }
    }

    public string myText
    {
        get => _myText;
        set
        {
            _myText = value;
            print($"React to some of this: {myInt}");
        }
    }

    void Awake()
    {
        myInt *= 2;
    }
}

// Downside: Way too messy, need to guess variables, don't get IDE autocomplete, enum only postpones the maintenance doom
class funcset
{
    public int myInt = 5;
    public string myText = "Donk";

    void Awake()
    {
        dynamic _ = GetVariable("myInt");
        SetVariable("myInt", _ * 2);
    }

    void SetVariable(string variableName, object variableValue)
    {
        switch (variableName)
        {
            case nameof(myInt):
            {
                myInt = (int)variableValue;
                break;
            }

            case nameof(myText):
            {
                myText = (string)variableValue;
                break;
            }
        }
    }

    dynamic GetVariable(string variableName)
    {
        switch (variableName)
        {
            case nameof(myInt):
            {
                return myInt;
            }

            case nameof(myText):
            {
                return myText;
            }
        }

        return null;
    }
}

// Downside: It's less messy than above, but its equally unmaintainable and its less performant than above
class reflection
{
    public int myInt = 5;
    public string myText = "Donk";

    void Awake()
    {
        // GetField from GetMethod from GetType, you know what goes here
        // SetField from method cached above
    }
}

// Does it exist? If not, is there something equally effective? Its clear, readible, performant 
class actualListener
{
    public int myInt = 5;
    public string myText = "Donk";

    myInt.onChange.AddListener(() => print($"React to some of this: {myInt}"));
    myText.onChange.AddListener(() => print($"React to some of this: {myText}"));
}

Recommended Answers

All 3 Replies

I don't know if this would work but how about creating a textbox and making it invisible? You could use that textbox as your variable. Then you could attach on OnChange handler to it that would trigger whenever it is updated. As for how to trigger an event when it is read, I don't know how you could do that. I also don't know why you would do that. What is the point in doing extra processing when a variable is read?

I'll try this in vb after I walk the dog. If it works in vb it should work in c#

It provides name of the variablenot the variable itself, which I would need to use reflection to read from to process it. Otherwise I would still have to resort to get/set.

Edit: I cannot use a textbox, this is a Unity C# script. There's no defacto WPF UI I have access to.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.