# c# Tieing variables

This topic is 1326 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

The problem I am trying to figure out has to do with passing variables about a variable geometry network.

Say you have three components. A B C, each has input variables and output variables.

A has three inputs a1,a2,a3  and generates three values A1,A2,A3

B has three inputs a1,b1,A3 and generates three values B1,B2,B3

C has three inputs c1,B2,A2 and generates three values C1,C2,C3

Because of the nature of the code, I could have hundreds of these things and I am trying to come up with a way of linking them together.

In C++ I would just take a pointer to A3 as an input to function B, then whenever B runs it has the latest value

The same for B2 and A2 in function C

(actually I normally have a dependency manager and ref counted variables so the network can be dynamic, but that's out of the scope of this question)

However I want to avoid using unsafe mode if I can.

Any of you come across a nice clean solution to this issue ?

##### Share on other sites

In C++ I would just take a pointer to A3 as an input to function B, then whenever B runs it has the latest value

So are you trying to do something like this?

// C++
class A
{
public:

int A3;

}

class B
{
public:
B(int* a3)
: a3_(a3)
{}

void Run()
{
cout << *a3_;
}

int* a3_;
}


You could use a delegate to achieve something like that in c#

// C#
class A
{

public int A3 {get;set;}
}

class B
{
public B(Func<int> getA3)
{
_getA3 = getA3;
}

public void Run()
{
Console.Write(_getA3());
}

public Func<int> _getA3;
}

int main()
{
var a = new A();
var b = new B(() => a.A3);

b.Run();

}



There are probably better ways of doing that if you explain what you're trying to achieve more clearly

##### Share on other sites

I'm not really sure what the problem or question is, but I think what you are describing falls under the term reactive programming.

This seems like it could be what you are looking for but I have only seen it myself as of 5 minutes ago: Reactive Extensions

If you want to build something yourself I'd suggest encapsulating the inputs in a class. That way you can still store references to them, update them and have the values updated in the nodes that use them.

// pseudocode
class Value<T> {
event valueChanged; // notifies event change
property T value {get; set; } // call event delegates when set
}


##### Share on other sites

Yes reactive programming seems to be the basic principle I need.

I don't want to have events flying around though, I'm thinking now I can simply have a class as a new type.

something along the lines of.  (not tested yet, not even sure it would compile, but you get the idea  )

class Variable
{
List<ref object> tied_objects = new List<ref object>();
object _value;

object value {
get {return _value;}
set {
_value=Value;
foreach (ref object o in tied_objects)
o = _value;
}

}
}



##### Share on other sites
How about actually using the same reference when they're shared?

using System.Collections.Generic;
using System.Linq;

class Variable
{
public object Value;
}

class Component
{
public List<Variable> Inputs;
public List<Variable> Outputs;

public Component(int numInputs, int numOutputs)
{
// (LINQ shorthand for: 'Inputs = new List<Variable>(numInputs); for (int i=0; i<numInputs; ++i) Inputs[i] = new Variable();')
Inputs = Enumerable.Range(0, numInputs).Select(x => new Variable()).ToList();
Outputs = Enumerable.Range(0, numOutputs).Select(x => new Variable()).ToList();
}

public virtual void Update()
{
// Read from the various Inputs[x].Values and Write to the various Outputs[x].Values
}

public void Update(params object[] inputValues)
{
for (int i=0; i<inputValues.Length && i < Inputs.Count; ++i)
Inputs[i].Value = inputValues[i];

Update();
}
}

class Program
{
static void Main(string[] args)
{
Component A = new Component(3,3);
Component B = new Component(3,3);
Component C = new Component(3,3);

// Since "Variable" is a reference type, they can be shared directly.
B.Inputs[2] = A.Outputs[2];

C.Inputs[1] = B.Outputs[1];
C.Inputs[2] = A.Outputs[1];
}
}

The potential downside of this is that the effect is bidirectional; If your code sets an input that's tied to a different component's output, the output value will change (obviously, since the variable is the same).

If you never explicitly set the value of a tied output, this will work fine. Otherwise, you can easily introduce strange bugs, especially if your component graph forks a lot.

If you want data to only flow one way, events are the easiest way. Edited by Nypyren

• 22
• 10
• 19
• 14
• 14