0
0
C Sharp (C#)programming~15 mins

Custom event arguments in C Sharp (C#) - Deep Dive

Choose your learning style9 modes available
Overview - Custom event arguments
What is it?
Custom event arguments are special classes you create to send extra information when an event happens in C#. Instead of just knowing that something occurred, you can pass details about that event. This helps the event handler understand the context and respond properly. It is a way to make events more useful and informative.
Why it matters
Without custom event arguments, events can only tell that something happened but not what exactly happened or any details about it. This limits how well your program can react to events. Custom event arguments let you send meaningful data with events, making your programs smarter and more interactive. Imagine a fire alarm that only says 'fire' versus one that says 'fire in kitchen at 3rd floor'—the second is much more helpful.
Where it fits
Before learning custom event arguments, you should understand basic events and delegates in C#. After mastering custom event arguments, you can explore advanced event patterns like event bubbling, asynchronous events, or using event arguments in UI frameworks like WPF or WinForms.
Mental Model
Core Idea
Custom event arguments are like personalized message envelopes that carry extra details along with an event notification.
Think of it like...
Imagine sending a letter (event) to a friend. A custom event argument is like adding a detailed note inside the envelope explaining why you are writing, so your friend knows exactly what to do when they read it.
Event Publisher ──► Event Raised ──► Custom Event Args ──► Event Handler

┌───────────────┐      ┌───────────────┐      ┌────────────────────┐      ┌───────────────┐
│ Publisher     │─────▶│ Event Raised  │─────▶│ Custom Event Args   │─────▶│ Event Handler │
└───────────────┘      └───────────────┘      └────────────────────┘      └───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding basic events in C#
🤔
Concept: Learn what events are and how they notify when something happens.
In C#, an event is a way for one part of a program to tell another part that something happened. For example, a button click event tells your program when the button is pressed. Events use delegates, which are like pointers to methods that will run when the event occurs.
Result
You can create and subscribe to simple events that notify without extra data.
Understanding events as notifications is the foundation for adding more detailed information later.
2
FoundationUsing EventArgs for basic event data
🤔
Concept: Learn about the built-in EventArgs class used to send simple event data.
The EventArgs class is the base class for event data in C#. It is empty and used when no extra information is needed. Events often have a signature like void Handler(object sender, EventArgs e). This means the event sends the sender and some event data (which can be empty).
Result
You can handle events that only tell that something happened, without details.
Knowing EventArgs is the default event data type helps you see why custom event arguments are needed for more info.
3
IntermediateCreating a custom event arguments class
🤔Before reading on: do you think you can add any data you want to an event by making a new class? Commit to your answer.
Concept: Learn how to define your own class that inherits from EventArgs to carry custom data.
To send extra information with an event, create a class that inherits from EventArgs. Add properties to this class for the data you want to send. For example, a TemperatureChangedEventArgs class might have a property for the new temperature value.
Result
You have a new event argument class that can carry specific data when the event fires.
Understanding inheritance from EventArgs is key to making custom event data that fits your needs.
4
IntermediateRaising events with custom arguments
🤔Before reading on: do you think you must create a new delegate type to use custom event arguments? Commit to your answer.
Concept: Learn how to raise events using your custom event arguments and the standard EventHandler delegate.
Instead of creating a new delegate, use the generic EventHandler where T is your custom event args class. When raising the event, create an instance of your custom args with the data and pass it to the event handler. This keeps your code clean and consistent.
Result
Your event can now send detailed information to subscribers using your custom event arguments.
Knowing about EventHandler simplifies event declaration and usage with custom data.
5
AdvancedSubscribing and handling custom event arguments
🤔Before reading on: do you think event handlers must cast EventArgs to your custom type manually? Commit to your answer.
Concept: Learn how to write event handlers that receive and use your custom event arguments safely and cleanly.
When subscribing to an event with custom arguments, your handler method should match the signature void Handler(object sender, YourCustomEventArgs e). This way, you get direct access to the custom properties without casting. Use the data inside the handler to respond appropriately.
Result
Event handlers can access detailed event data easily and respond accordingly.
Matching handler signatures to custom event args avoids errors and makes code clearer.
6
AdvancedBest practices for custom event arguments
🤔Before reading on: do you think event argument classes should be mutable or immutable? Commit to your answer.
Concept: Learn how to design your custom event argument classes for safety and clarity.
It is best to make your custom event argument classes immutable after creation. Use readonly properties and set values only in the constructor. This prevents accidental changes to event data after the event is raised, making your program more reliable.
Result
Your event data is safe from unintended changes, improving program stability.
Understanding immutability in event args prevents bugs caused by changing event data unexpectedly.
7
ExpertAdvanced event argument patterns and pitfalls
🤔Before reading on: do you think passing large data in event arguments is always a good idea? Commit to your answer.
Concept: Explore advanced considerations like performance, memory, and event argument reuse.
Passing large objects or collections in event arguments can hurt performance and cause memory issues. Sometimes, passing references or IDs is better. Also, avoid reusing event argument instances across events to prevent confusing data. Experts design event args carefully balancing detail and efficiency.
Result
You write efficient, safe event code that scales well in real applications.
Knowing the tradeoffs in event argument design helps avoid subtle bugs and performance problems.
Under the Hood
When an event is raised, the .NET runtime calls all subscribed event handlers in order. The event arguments object is created before raising the event and passed as a parameter. Custom event arguments are just normal objects inheriting from EventArgs, so they carry data like any other object. The event handlers receive this object reference and can read its properties. This mechanism allows flexible data passing without changing the event system itself.
Why designed this way?
The event system in .NET was designed to be simple and extensible. Using a base EventArgs class allows any custom data to be passed without changing the event delegate types. The generic EventHandler delegate was introduced later to avoid creating many delegate types. This design balances type safety, flexibility, and backward compatibility.
┌───────────────┐
│ Event Raised  │
└──────┬────────┘
       │ creates
       ▼
┌────────────────────┐
│ Custom EventArgs    │
│ (data properties)  │
└──────┬─────────────┘
       │ passed to
       ▼
┌───────────────┐
│ Event Handler │
│ (reads data)  │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do you think you must create a new delegate type for every custom event argument class? Commit to yes or no.
Common Belief:You must create a new delegate type for each custom event argument class to handle events properly.
Tap to reveal reality
Reality:You can use the generic EventHandler delegate with your custom event argument class, avoiding the need for new delegate types.
Why it matters:Creating unnecessary delegate types clutters code and makes maintenance harder.
Quick: Do you think event handlers receive copies of event arguments or references? Commit to your answer.
Common Belief:Event handlers receive copies of event arguments, so changing them inside handlers won't affect others.
Tap to reveal reality
Reality:Event handlers receive references to the same event argument object, so changes affect all handlers.
Why it matters:Mutating event arguments inside handlers can cause unexpected side effects and bugs.
Quick: Do you think it's okay to reuse the same event argument instance for multiple events? Commit to yes or no.
Common Belief:Reusing the same event argument instance for multiple events is efficient and safe.
Tap to reveal reality
Reality:Reusing event argument instances can cause data confusion and bugs because handlers may see stale or wrong data.
Why it matters:Reusing instances breaks the assumption that event data is unique per event, leading to hard-to-find errors.
Quick: Do you think passing large data objects in event arguments is always a good idea? Commit to yes or no.
Common Belief:Passing large data objects in event arguments is fine and has no downside.
Tap to reveal reality
Reality:Passing large data can hurt performance and increase memory use; sometimes passing references or summaries is better.
Why it matters:Ignoring performance impacts can make applications slow or crash under heavy event loads.
Expert Zone
1
Custom event arguments should be immutable to prevent accidental changes after the event is raised, which can cause subtle bugs.
2
Using EventHandler avoids delegate proliferation but requires understanding generic delegates and matching signatures.
3
Passing minimal necessary data in event arguments improves performance and reduces memory pressure in high-frequency events.
When NOT to use
Avoid custom event arguments when the event does not need to send extra data; use simple EventArgs instead. For very complex event data or asynchronous event handling, consider using specialized event systems or messaging frameworks like Reactive Extensions or event buses.
Production Patterns
In production, custom event arguments are used to pass context like user info, error details, or state changes. Patterns include immutable event args, using EventHandler, and careful design to avoid large payloads. Logging and telemetry systems often rely on custom event arguments to capture rich event data.
Connections
Observer pattern
Custom event arguments build on the observer pattern by adding detailed data to notifications.
Understanding custom event arguments deepens your grasp of how observers communicate rich information, not just signals.
Immutable objects
Custom event arguments are often designed as immutable objects to ensure data consistency.
Knowing immutability principles helps you design safer event data that cannot be changed unexpectedly.
Messaging systems in distributed computing
Custom event arguments are like message payloads in distributed systems, carrying data between components.
Seeing event arguments as messages helps understand data flow and decoupling in large software architectures.
Common Pitfalls
#1Mutating event argument properties inside event handlers.
Wrong approach:void OnTemperatureChanged(object sender, TemperatureChangedEventArgs e) { e.NewTemperature = 100; // Wrong: changing event data }
Correct approach:void OnTemperatureChanged(object sender, TemperatureChangedEventArgs e) { var temp = e.NewTemperature; // Read-only usage }
Root cause:Misunderstanding that event arguments should be immutable and treated as read-only data.
#2Creating a new delegate type unnecessarily for custom event arguments.
Wrong approach:public delegate void TemperatureChangedHandler(object sender, TemperatureChangedEventArgs e); public event TemperatureChangedHandler TemperatureChanged;
Correct approach:public event EventHandler TemperatureChanged;
Root cause:Not knowing about the generic EventHandler delegate provided by .NET.
#3Reusing the same event argument instance for multiple event raises.
Wrong approach:var args = new TemperatureChangedEventArgs(25); TemperatureChanged?.Invoke(this, args); args = new TemperatureChangedEventArgs(30); TemperatureChanged?.Invoke(this, args); // Reusing variable but creating new instances is okay // But reusing the same instance and changing property would be wrong.
Correct approach:TemperatureChanged?.Invoke(this, new TemperatureChangedEventArgs(25)); TemperatureChanged?.Invoke(this, new TemperatureChangedEventArgs(30));
Root cause:Confusing variable reuse with object reuse; event args should be new instances per event.
Key Takeaways
Custom event arguments let you send detailed information with events, making your program more responsive and informative.
They are classes that inherit from EventArgs and carry properties with event data.
Use the generic EventHandler delegate to simplify event declarations with custom arguments.
Design event argument classes to be immutable to avoid bugs caused by changing data after event raising.
Avoid passing large data in event arguments to keep your program efficient and responsive.