?
Solved

Is it possible to handle and raise events through extension methods?

Posted on 2011-04-27
8
Medium Priority
?
190 Views
Last Modified: 2012-05-11
Hello,

Please see the attached code.

You'll notice that CObject has an event that is raised when the field is changed, however what I'm wanting to achieve is to be able to handle this event using an extension method in the CObjectCollectionExtensions class and then raise this event from the CObjectCollectionExtensions class so that rather than other classes having to subscribe to the events of the individual CObject class, they can simply subscribe to the object of CCollection<CObject>. So I could have something like:

public class TestClass {

	public void TestMethod(){

		CCollection<CObject> mObjectCollection=new CCollection<CObject>();

		mObjectCollection.FieldChangeEventHandler+=new mObjectCollection.FieldChangeEventHandler(FieldChangeHandler);

	}

	public void FieldChangeHandler(CObject aSender) {
		//Do things with the sender.
	}

}

Open in new window


Is there a nice way of achieving this?

Thanks,
Uni
public class CObject {

	public delegate void FieldChange(CObject aSender);
	public event FieldChange FieldChangeEventHandler;

	private int mField;

	public int GetField(){
		return mField;
	}

	public void SetField(int aField){
		mField=aField;
		if(FieldChangeEventHandler!=null)
			FieldChangeEventHandler(this);
	}

}



public class CCollection<T>{

	private List<T> mList;

	public CCollection(){
		mList=new List<T>();
	}

	public void Add(T a){
		mList.Add(a);
	}

	public void Remove(int aIndex){
		mList.RemoveAt(aIndex);
	}

	public int GetNumberOfObjects(){
		return mList.Count;
	}

	public T GetObject(int aIndex){
		return mList[aIndex];
	}

}



public static class CObjectCollectionExtensions{

	public static CObject GetObjectByField(this CCollection<CObject> aCollection, int mField){
		for(int tIndex=0;tIndex<aCollection.GetNumberOfObjects();tIndex++){
			if(aCollection.GetObject(tIndex).GetField()==mField)
				return aCollection.GetObject(tIndex);
		}
		return null;
	}

}

Open in new window

0
Comment
Question by:Unimatrix_001
  • 4
  • 4
8 Comments
 
LVL 33

Accepted Solution

by:
Todd Gerbert earned 2000 total points
ID: 35475380
I don't think extension methods are what you want - logically it doesn't really make sense, since extension methods are intended to extend the functionality of a given class by operating on instances of that class (e.g. a "ToFrench()" method on a String object), but that's not really what you're doing here.

Technically it probably won't work since the first parameter of an extension method is always a reference to the class it's extending (a CCollection<CObject>), whereas your event requires delegates that take a single parameter of type "CObject".

I'm not too sure I'm following exactly what you're trying to achieve, your example is a little too abstract for my pre-coffee brain. ;)
0
 
LVL 3

Author Closing Comment

by:Unimatrix_001
ID: 35475423
Appreciate the reply - thanks. Somehow I didn't think extensions would help here... Oh well, thanks anyways. :)

Uni
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35475439
You know, you could just have CCollection<CObject> subscribe to each CObject's FieldChange event as they're added to the collection, in CCollection<CObject>.Add() (and likewise do the inverse in CCollection<CObject>.Remove()), then CCollection<CObject> will handle each CObject's FieldChange with the same private member method, and can in turn raise it's own event.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Author Comment

by:Unimatrix_001
ID: 35475473
Hm, it's not quite as tidy as I had hoped - I think I'll just stick to inheritance... I'm just creating a new collection class and inheriting from the CCollection class - makes the code a little clearer as well I suppose.

Thanks for your help,
Uni
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35475495
e.g.:

class MyObject
{
	private int _myField;
	public event EventHandler FieldChanged;

	protected virtual void OnFieldChanged(EventArgs e)
	{
		if (FieldChanged != null)
			FieldChanged(this, e);
	}

	public int MyField
	{
		get { return _myField; }
		set
		{
			_myField = value;
			OnFieldChanged(new EventArgs());
		}
	}
}

class MyCollection : Collection<MyObject>
{
	public event EventHandler MemberFieldChanged;

	protected override void InsertItem(int index, MyObject item)
	{
		item.FieldChanged += new EventHandler(item_FieldChanged);
		base.InsertItem(index, item);
	}

	protected override void RemoveItem(int index)
	{
		Items[index].FieldChanged -= item_FieldChanged;
		base.RemoveItem(index);
	}

	protected virtual void OnMemberFieldChanged(EventArgs e)
	{
		if (MemberFieldChanged != null)
			MemberFieldChanged(this, e);
	}

	void item_FieldChanged(object sender, EventArgs e)
	{
		OnMemberFieldChanged(new EventArgs());
	}
}

Open in new window

0
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 35475509
Heh, that's next to identical to what I've got here! :)
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35475545
Great minds think alike.

Incidentally, I believe the latest Framework has some built-in classes that achieve this effect - I'm not a big database guy so I'm not too familiar with them, but you can have a look at http://msdn.microsoft.com/en-us/library/ms668604.aspx for a starting poing (and/or Google "observable collections").
0
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 35475571
Can't say I've heard of them before - I'll have a bit of a look into them - seems I may be re-inventing the wheel...
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question