[C#] Class Member Var Value Change Notification's Using Custom Interface [Example]

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
Here's a nice quick example i've created, which utilizes an interface, events, delegates, and all that to raise events for notification's whenever a class instance's member variable changes:

C#:
private void MainMethod()
{
	MyClass cls = new MyClass();
	cls.VarChanged += new VariableNotifications.VarChangedEvent<int>(p_VarChanged);

	MessageBox.Show("Now changing the ID member value for the instance of MyClass: cls");
	cls.ID = 233;
}

public class MyClass : VariableNotifications
{
	private int _ID;
	public int ID
	{
		get { return _ID; }
		set
		{
			if (_ID != value)
			{
				_ID = value;
				RaiseChangedEvent("ID", _ID);
			}
		}
	}
}

private void p_VarChanged(object sender, VarChangedEventArgs<int> e)
{
	MessageBox.Show(string.Format("Member variable ({1}) from the class ({0}) has changed to a value of ({2})", 
		sender.GetType().Name, e.VarName, e.varValue));
	
}

public class VariableNotifications : IVariableChangedNotify<int>
{
	public delegate void VarChangedEvent<T>(object sender, VarChangedEventArgs<T> value);
	public event VarChangedEvent<int> VarChanged;

	public void RaiseChangedEvent(string VarName, int VarValue)
	{
		VarChangedEvent<int> handle = this.VarChanged;
		if (handle != null)
		{
			VarChangedEventArgs<int> VarArgs = new VarChangedEventArgs<int>(VarName, VarValue);
			handle(this, VarArgs);
		}
	}
}

public class VarChangedEventArgs<T>
{
	public string VarName { get; set; }
	public T varValue { get; set; }

	public VarChangedEventArgs(string varName, T args)
	{
		VarName = varName;
		varValue = args;
	}
}

public interface IVariableChangedNotify<T>
{
	void RaiseChangedEvent(string VarName, T VarValue);
}

I actually quite enjoy this kind of layout as well. It's all nice and clean, and there's lots of good stuff in this short example i've come up with.

(I'm fooling around in my C# IDE right now, so i've been posting random stuff today, but this is good for learning).

If you don't understand what is going on just post within this thread and i'll explain my code.

Note: If you'll notice, I have this:
C#:
if (_ID != value)
{
	_ID = value;
	RaiseChangedEvent("ID", _ID);
}

This is mainly because if the value in this example is 5, and it's set to 5, then since it's the same value, it hasn't really changed to a different value, perceptively, although it has changed programatically, but I don't want to monitor it being changed to the same value here. If you want this, then just remove the if statement and you'll receive notifications for if it changes to the same value.

Here's the output:
ad07w.png


:beerchug2:
 
Last edited:
Somebody must know C# around here :( I always feel like an outcast posting this stuff because I never get any replies lol.
 
Afraid I don't know C# - I read your threads though.

I understand some of the code - the interface is the Get and Set code at the start of the class? I don't follow what happens after RaiseChangedEvent is called though.
 
I'll try to explain as much of my code as I can.

Here's my class
C#:
public class MyClass : VariableNotifications
{
	private int _ID;
	public int ID
	{
		get { return _ID; }
		set
		{
			if (_ID != value)
			{
				_ID = value;
				RaiseChangedEvent("ID", _ID);
			}
		}
	}
}

We have a backing member variable (_ID) which is for the property ID. If we're setting this value at runtime, the if statement checks to see if the value we're setting it to is equal to it's current value. If it's the same as the current value, then we don't do anything, else, we change the value of the property (of type int/Int32), and raise the RaiseChangedEvent() method. (I'll explain what that's for later.)

Note, that our class inherits the class i've created (VariableNotifications), and this class inherits the custom interface IVariableChangedNotify with <T> as a type of integer (int/Int32).

My Interface (IVariableChangedNotify) looks like this, with one method:
C#:
public interface IVariableChangedNotify<T>
{
	void RaiseChangedEvent(string VarName, T VarValue);
}

Thus, when we inherit this interface from the class, VariableNotifications, we have to implement this method. You'll see RaiseChangedEvent() in my VariableNotifications class:
Code:
public class VariableNotifications : IVariableChangedNotify<int>
{
	public delegate void VarChangedEvent<T>(object sender, VarChangedEventArgs<T> value);
	public event VarChangedEvent<int> VarChanged;
 
	public void RaiseChangedEvent(string VarName, int VarValue)
	{
		VarChangedEvent<int> handle = this.VarChanged;
		if (handle != null)
		{
			VarChangedEventArgs<int> VarArgs = new VarChangedEventArgs<int>(VarName, VarValue);
			handle(this, VarArgs);
		}
	}
}

In here we create our delegate for the signature where in VarChangedEvent<T>, T represents type integer (int/Int32) because that's what we specified. So we have parameters of sender which is a type of System.Object, and value, which is a type of my custom class VarChangedEventArgs<T>.

Note, in that class we have 2 member variables:
C#:
public class VarChangedEventArgs<T>
{
	public string VarName { get; set; }
	public T varValue { get; set; }
 
	public VarChangedEventArgs(string varName, T args)
	{
		VarName = varName;
		varValue = args;
	}
}

VarName, and varValue, in which varValue is type of <T> which we have declared as int as you've seen. In the constructor, which accepts 2 params, we can set both of these.

>> Back to the class i've made: public class VariableNotifications : IVariableChangedNotify<int>

We create our event:
C#:
public event VarChangedEvent<int> VarChanged;

And assign it; if it's not null:
C#:
VarChangedEventArgs<int> VarArgs = new VarChangedEventArgs<int>(VarName, VarValue);

Then we create our instance of the VarChangedEventArgs<T> class where <T> is a type of int, and through the constructor assign values VarName, and VarValue to their respective parameter slots.

Then for the event, which was assigned to handle:
C#:
handle(this, VarArgs);

We pass the current class object to the first param, and VarArgs, the instance of VarChangedEventArgs<T>, to the second param.

Now to the main method:
Code:
private void MainMethod()
{
	MyClass cls = new MyClass();
	cls.VarChanged += new VariableNotifications.VarChangedEvent<int>(p_VarChanged);
 
	MessageBox.Show("Now changing the ID member value for the instance of MyClass: cls");
	cls.ID = 233;
}

We create our instance of MyClass, in which we want to monitor the changes of those member variables. And assign an event handler to the method p_VarChanged in which matches the delegate signature of VariableNotifications.VarChangedEvent<T> where <T> is again a type of int in this case. This makes sure that we have our monitoring method in place.

The messagebox is just there to show that we're just about to change the value of the instance of MyClass's variable, ID to a value of 233, and you'll see the result of the change, as a notification in a messagebox for the class that this member resides in, along with it's name, and updated value. Because we defined all of that stuff back when we called RaiseChangedEvent().

C#:
RaiseChangedEvent("ID", _ID);

Both the parameters in here, are values which eventually get placed within the member values of the class instance for VarChangedEventArgs<T>. Respectively, VarName, and varValue, from param1, to param2.

So when this method is called:
C#:
private void p_VarChanged(object sender, VarChangedEventArgs<int> e)
{
	MessageBox.Show(string.Format("Member variable ({1}) from the class ({0}) has changed to a value of ({2})", 
		sender.GetType().Name, e.VarName, e.varValue));
 
}

e of type of VarChangedEventArgs<int>, holds values for both VarName, and varValue, as you can see here:

Code: MessageBox.Show(string.Format("Member variable ({1}) from the class ({0}) has changed to a value of ({2})",
sender.GetType().Name, e.VarName, e.varValue));

Hope that was a good enough explanation.
 
Thanks for the explanation - it makes more sense now. It seems interesting, how would this get used in a full program?

I'm still stuck in the phase between trivial programs and useful ones, gradually working out how to design something useful.
 
This in a full program... Perhaps you have instances of the same class multiple times, and things are being called asynchronously from multiple threads all at the same time in the background. For one, it's easy enough to determine which thread changed a property in that particularly created instance, where that instance was created (which thread), and which value was modified, and what the new value is.

You can adapt this to something quite spectacular depending on the complexity of your program :)

Servers/Sockets/WebRequests/Filesystems/etc...

Anything. I can't think of an exact example, but perhaps you have some method which parses a value, and based on a value or condition, modifies a field in that instance of a particular class. Blindly checking all the fields within this instance? Or having it tell you by itself? :)

Much faster, and more efficient, and on top of that, it has a bit of a "coolness" factor to it when you can pull that off!
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top