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!?