Home > front end >  Is there way to pass a property or field by reference to update it in a function?
Is there way to pass a property or field by reference to update it in a function?

Time:03-25

I have a small bit of code that assigns a node to fields called NodeA and NodeB. But the code is rather duplicated and so feels like I could simplify it into a function. But I am wondering if I can reference an actual field in a class to assign to a specific field?

My field/property is setup like this:

public class Test {

    private Node _nodeA;
    private Node _nodeB;

    public void Set(Node nodeA, Node nodeB){

        if (_nodeA != null)
            _nodeA.OnChange -= Update;
        _nodeA = nodeA;
        _nodeA.OnChange  = Update;

        if (_nodeB != null)
            _nodeB.OnChange -= Update;
        _nodeB = nodeB;
        _nodeB.OnChange  = Update;  

    }

    void Update(){}//todo

}

I want to put this into a simple function so I can pass in the node but also a reference pointing to the field that I want to assign it to.... something along this idea (pseudo code)

Set(Node node, /* pointer to _nodeA or _nodeB */ ptr) 
{
   if(ptr != null) ptr.OnChange -= Update;
   ptr = node;
   ptr.OnChange  = Update;
}
Set(nodeA, /* pointer to field _nodeA */ );
Set(nodeB, /* pointer to field _nodeB */ );

Is it possible to create a function like Set in C# ? If so how do i pass such a reference to a field like that?

CodePudding user response:

Use the ref keyword. That way you can change the underlying assignment.

Here's a simplified version:

using System;
                    
public class Program
{
    public static void Main()
    {
        // print the original node values
        Console.WriteLine(Test._nodeA.Message);
        Console.WriteLine(Test._nodeB.Message);
        
        // modify the two nodes using a brand new instance
        Test.Set(ref Test._nodeA, new Node { Message = "modified a" });
        Test.Set(ref Test._nodeB, new Node { Message = "modified b" });
        
        // print out the new node data
        Console.WriteLine(Test._nodeA.Message);
        Console.WriteLine(Test._nodeB.Message);
    }
}

public static class Test
{
    // these need to be public so that the code CALLING "Set" can use these fields
    public static Node _nodeA = new Node { Message = "start a" };
    public static Node _nodeB = new Node { Message = "start b" };
    
    public static void Set(ref Node target, Node newVal)
    {
        // all this does is simple reassignment, but it's to the
        // same reference location in memory that _nodeA/_nodeB holds.
        // you can add more complex logic as well.
        target = newVal;

        // because target and newVal have the same memory ref
        // you can modify them interchangeably and they effect each other
        target.Message  = "!";
        newVal.Message  = "?";
    }
}

public class Node
{
    public string Message {get;set;}
}

The Set method's first parameter uses ref, which allows you to reassign the passed instance in its original location.

This prints

start a
start b
modified a!?
modified b!?
  •  Tags:  
  • c#
  • Related