Method call if not null in C# - c#

Is it possible to somehow shorten this statement?
if (obj != null)
obj.SomeMethod();
because I happen to write this a lot and it gets pretty annoying. The only thing I can think of is to implement Null Object pattern, but that's not what I can do every time and it's certainly not a solution to shorten syntax.
And similar problem with events, where
public event Func<string> MyEvent;
and then invoke
if (MyEvent != null)
MyEvent.Invoke();

From C# 6 onwards, you can just use:
MyEvent?.Invoke();
or:
obj?.SomeMethod();
The ?. is the null-propagating operator, and will cause the .Invoke() to be short-circuited when the operand is null. The operand is only accessed once, so there is no risk of the "value changes between check and invoke" problem.
===
Prior to C# 6, no: there is no null-safe magic, with one exception; extension methods - for example:
public static void SafeInvoke(this Action action) {
if(action != null) action();
}
now this is valid:
Action act = null;
act.SafeInvoke(); // does nothing
act = delegate {Console.WriteLine("hi");}
act.SafeInvoke(); // writes "hi"
In the case of events, this has the advantage of also removing the race-condition, i.e. you don't need a temporary variable. So normally you'd need:
var handler = SomeEvent;
if(handler != null) handler(this, EventArgs.Empty);
but with:
public static void SafeInvoke(this EventHandler handler, object sender) {
if(handler != null) handler(sender, EventArgs.Empty);
}
we can use simply:
SomeEvent.SafeInvoke(this); // no race condition, no null risk

What you're looking for is the Null-Conditional (not "coalescing") operator: ?.. It's available as of C# 6.
Your example would be obj?.SomeMethod();. If obj is null, nothing happens. When the method has arguments, e.g. obj?.SomeMethod(new Foo(), GetBar()); the arguments are not evaluated if obj is null, which matters if evaluating the arguments would have side effects.
And chaining is possible: myObject?.Items?[0]?.DoSomething()

A quick extension method:
public static void IfNotNull<T>(this T obj, Action<T> action, Action actionIfNull = null) where T : class {
if(obj != null) {
action(obj);
} else if ( actionIfNull != null ) {
actionIfNull();
}
}
example:
string str = null;
str.IfNotNull(s => Console.Write(s.Length));
str.IfNotNull(s => Console.Write(s.Length), () => Console.Write("null"));
or alternatively:
public static TR IfNotNull<T, TR>(this T obj, Func<T, TR> func, Func<TR> ifNull = null) where T : class {
return obj != null ? func(obj) : (ifNull != null ? ifNull() : default(TR));
}
example:
string str = null;
Console.Write(str.IfNotNull(s => s.Length.ToString());
Console.Write(str.IfNotNull(s => s.Length.ToString(), () => "null"));

Events can be initialized with an empty default delegate which is never removed:
public event EventHandler MyEvent = delegate { };
No null-checking necessary.
[Update, thanks to Bevan for pointing this out]
Be aware of the possible performance impact, though. A quick micro benchmark I did indicates that handling an event with no subscribers is 2-3 times slower when using the the "default delegate" pattern. (On my dual core 2.5GHz laptop that means 279ms : 785ms for raising 50 million not-subscribed events.). For application hot spots, that might be an issue to consider.

Yes, in C# 6.0 -- https://msdn.microsoft.com/en-us/magazine/dn802602.aspx.
object?.SomeMethod()

This article by Ian Griffiths gives two different solutions to the problem that he concludes are neat tricks that you should not use.

Cerating extention method like one suggested does not really solve issues with race conditions, but rather hide them.
public static void SafeInvoke(this EventHandler handler, object sender)
{
if (handler != null) handler(sender, EventArgs.Empty);
}
As stated this code is the elegant equivalent to solution with temporary variable, but...
The problem with both that it's possible that subsciber of the event could be called AFTER it has unsubscribed from the event. This is possible because unsubscription can happen after delegate instance is copied to the temp variable (or passed as parameter in the method above), but before delegate is invoked.
In general the behaviour of the client code is unpredictable in such case: component state could not allow to handle event notification already. It's possible to write client code in the way to handle it, but it would put unnecesssary responsibility to the client.
The only known way to ensure thread safity is to use lock statement for the sender of the event. This ensures that all subscriptions\unsubscriptions\invocation are serialized.
To be more accurate lock should be applied to the same sync object used in add\remove event accessor methods which is be default 'this'.

I agree with the answer by Kenny Eliasson. Go with Extension methods. Here is a brief overview of extension methods and your required IfNotNull method.
Extension Methods ( IfNotNull method )

Maybe not better but in my opinion more readable is to create an extension method
public static bool IsNull(this object obj) {
return obj == null;
}

I have made this generic extension that I use.
public static class ObjectExtensions {
public static void With<T>(this T value, Action<T> todo) {
if (value != null) todo(value);
}
}
Then I use it like below.
string myString = null;
myString.With((value) => Console.WriteLine(value)); // writes nothing
myString = "my value";
myString.With((value) => Console.WriteLine(value)); // Writes `my value`

There is a little-known null operator in C# for this, ??. May be helpful:
http://weblogs.asp.net/scottgu/archive/2007/09/20/the-new-c-null-coalescing-operator-and-using-it-with-linq.aspx

Related

Is it possible to write a class that hides the difference between adding WeakEventManager handlers and traditional ones?

I have a C# (.NET 4.6.1) project that uses a lot of events. I'm tempted to move all the event handlers to the new WeakEventManager pattern - to avoid endlessly worrying about deregistering handlers to avoid memory leaks.
However I have to do lots of testing for performance and want a way to switch between the two methods easily. So far I've been using conditional compilation to do this along the lines of :
#if WeakEvents
WeakEventManager<EventSource,EArgs>.AddHandler(source, "TheEvent", handler);
#else
source.TheEvent += handler;
#endif
This works, but its messy. Ideally I'd like to create a class that hides this away. ie create a class which internally can use either method. Then I can change all my source to attach handlers with the new class and switch easily (or even move to some new method in the future).
However I can't see how to write that class - because I can't pass the event as a parameter - and there would have to be some reflection going on with the handler/name which is beyond me.
Is there an easy way to do that?
Here is one way to do that:
static class EventHelper {
public static void Subscribe<TSource, TEventArgs>(TSource source, Expression<Func<TSource, EventHandler<TEventArgs>>> eventRef, EventHandler<TEventArgs> handler) where TEventArgs : EventArgs {
if (source == null)
throw new ArgumentNullException(nameof(source));
var memberExp = eventRef.Body as MemberExpression;
if (memberExp == null)
throw new ArgumentException("eventRef should be member access expression");
var eventName = memberExp.Member.Name;
#if WeakEvents
WeakEventManager<TSource, TEventArgs>.AddHandler(source, eventName, handler);
#else
// some reflection here to get to the event
var ev = source.GetType().GetEvent(eventName);
if (ev == null)
throw new ArgumentException($"There is no event with name {eventName} on type {source.GetType()}");
ev.AddMethod.Invoke(source, new object[] { handler });
#endif
}
}
Usage is as simple as:
// second parameter is event reference
EventHelper.Subscribe(source, s => s.TheEvent, Handler);

Why should I check for null before I invoke the custom event?

What is the difference between these two code samples for invoking an event?
Sample 1
public void OnDataChanged()
{
if (DataChanged != null)
{
DataChanged(this);
}
}
Sample 2
DataChanged.Invoke(this);
When should I use each method to invoke a custom event? And why sometimes I get a NullReferenceException when I try to invoke event using DataChanged.Invoke(this), but when I convert the event invocation to the method in Sample 1 the DataChanged never becomes null anymore?
An OnXYZ method should always follow this form:
public void OnXYZ()
{
var evt = XYZ;
if (evt != null)
evt(sender, e); // where to get e from differs
}
There are a couple of reasons for this form:
The if evt != null check ensures that we don't try to invoke a null delegate. This can happen if nobody has hooked up an event handler to the event.
In a multithreaded scenario, since delegates are immutable, once we've obtained a local copy of the delegate into evt, we can safely invoke it after checking for non-null, since nobody can alter it after the if but before the call.
What to pass for e differs, if you need to pass an EventArgs descendant with a parameter there are two ways:
public void OnXYZ(string p)
{
var evt = XYZ;
if (evt != null)
evt(sender, new SomeEventArgs(p));
}
or more commonly this:
public void OnXYZ(SomeEventArgs e)
{
var evt = XYZ;
if (evt != null)
evt(sender, e);
}
This syntax:
evt(sender, e);
is just a different way of writing this:
evt.Invoke(sender, e);
Also note that externally to your class, the event is an event, you can only add or remove event handlers from it.
Internal to your class, the event is a delegate, you can invoke it, check the target or method, walk the list of subscribers, etc.
Also, in C# 6 there is a new operator introduced, ?. - the Null-conditional operator - which is basically short for if not-null, dereference, which can shorten this method:
public void OnXYZ(SomeEventArgs e)
{
var evt = XYZ;
if (evt != null)
evt(sender, e);
}
into this:
public void OnXYZ(SomeEventArgs e)
{
XYZ?.Invoke(sender, e);
}
which can be further shortened with the use of Expression-bodied members:
public void OnXYZ(SomeEventArgs e) => XYZ?.Invoke(sender, e);
Please note that it is not possible to write this:
XYZ?.(sender, e);
so you must in this case use Invoke yourself.
when I convert the event invocation to the method in Sample 1 the DataChanged never becomes Null
Then you're simply looking at two different scenarios.
if you don't declare an event like public event EventHandler YourEvent = delegate { };, then YourEvent is null until some consumer subscribes to it.
If nothing has subscribed to DataChanged it will be set to null, and so when you attempt to do DataChanged.Invoke(this) you'll get a NullRefException as really it's trying to do null.Invoke(this). The reason for the additional if (DataChanged != null) is to avoid this occurring when nobody has subscribed to the event.
I don't believe that when you use Sample 1 DataChanged is never null, it's just never reaching the .Invoke to throw up the exception. It will always be null if nobody has subscribed.
Are you sure, that in Sample 1 the DataChanged is never null? Or you just don't get the NullReference Exception (because you check if DataChanged is not null in the if statement)?
Let's start with the basics. Event is a special kind of delegate. When you call DataChanged(this) and DataChanged.Invoke(this), it's the same thing. Why? Because it compiles to the same thing. So all in all the DataChanged(this) is just a shorthand for calling DataChanged.Invoke(this).
Now, why do we need to check for null reference (like in sample 1).
Basically, when you invoke an event, you invoke all methods that were subscribed to this event (e.g. DataChanged += someEventHandler).
If nobody subscribed to this event, it will have a null value. No method was assigned to handle this event. In other words: the event handler is null.
That's why it's a good practice to check for null, before invoking an event.
An Example:
public void OnAbc(){
var data=Abc;
if(!String.IsNullOrEmpty(data))
Abc(sender,e);
}

Decompiled assembly - unusual code

I decompiled an assembly using ILSpy, and one class in particular got my attention:
public class CustomTextStream : NetworkStream
{
private EventHandler<CustomEventArgs> someEvent;
public event EventHandler<CustomEventArgs> SomePublicEvent
{
add
{
EventHandler<CustomEventArgs> eventHandler = this.someEvent;
EventHandler<CustomEventArgs> eventHandler2;
do
{
eventHandler2 = eventHandler;
EventHandler<CustomEventArgs> value2 =
(EventHandler<CustomEventArgs>)Delegate.Combine(eventHandler2, value);
eventHandler =
Interlocked.CompareExchange<EventHandler<CustomEventArgs>>(
ref this.someEvent, value2, eventHandler2);
}
while (eventHandler != eventHandler2);
}
remove
{
// similar stuff...
}
}
}
Further in the code, seems like private delegate is used to fire an actual event:
if (something != null && somethingElse != 0)
{
this.someEvent(this, new CustomEventArgs(someArg));
}
The question: Can someone guess what could be the idea behind this custom accessors, assuming that some "compile/decompile magic" didn't take place? I'm not much familiar with IL, btw...
(Side note: the application is multi-threaded and utilizes networking, obviously.)
This is a new event handler code generated by compiler. It was introduced in C# 4 (C# 3 version was different)
Interlocked.CompareExchange compares first argument with third, and if they are equal, replaces first argument with second. This is a thread-safe operation. Loop is used for a case when after assigning a variable eventHandler2 and before check, another thread changes this delegate. In this case, Interlocked.CompareExchange does not perform exchange, loop condition does not evaluate to true and next attempt is made.
C# 3 generated simple code in event handlers:
add { lock(this) { changed = changed + value; } }
Which had lower performance and could introduce deadlocks.
There is a great series of articles on this subject:
Events get a little overhaul in C# 4
Events get a little overhaul in C# 4, Part II

When is it better practice to explicitly use the delegate keyword instead of a lambda?

Is there any best practice with respect to coding style with respect to explicit use of the delegate keyword instead of using a lambda?
e.g.
new Thread(() =>
{
// work item 1
// work item 2
}).Start();
new Thread(delegate()
{
// work item 1
// work item 2
}).Start();
I think the lambda looks better. If the lambda is better style, what's the point of having a delegate keyword, other than for the fact that it existed before lambdas were implemented?
Lambda syntax is much more generalised, and the designers have said that they'd ideally remove the old overlapping syntaxes (dont have a citation, but it's probably Eric Lippert or Jon Skeet in a book or a podcast).
But delegate allows you to ignore parameters, e.g.:
object.Event += delegate { };
versus having to say:
object.Event += (sender,args) => { };
which can be very useful in large argument lists and/or to make the code more resilient to refactoring.
EDIT: As pointed out by Yann Schwartz in another answer (now unfortunately deleted), a very neat usage of this trick is in order to provide a default hander for an event using the Null Object pattern:-
class MyClassThatFiresWithoutTheTrick
{
public event EventHandler MyEvent; // implicit = null
// Need a method to keep this DRY as each fire requires a null check - see Framework Design Guidelines by Abrams and Cwalina
protected virtual void OnMyEvent()
{
// need to take a copy to avoid race conditions with _removes
// See CLR via C# 3rd edition p 264-5 for reason why this happens to work
//var handler = MyEvent;
// BUT THIS is the preferred version
var handler = Interlocked.CompareExchange( ref MyEvent, null, null);
// Need to do this check as it might not have been overridden
if( handler == null)
return;
handler( this, EventArgs.Empty );
}
}
class MyClassThatFiresWithTheTrick
{
public event EventHandler MyEvent = delegate{};
protected virtual void OnMyEvent()
{
MyEvent( this, EventArgs.Empty );
}
}
(though what you might often end up doing is an Inline Method of OnMyEvent, making the code even shorter again.)

Raising an event thread safely

I'm sure I've seen this around before but I'm wondering how I should raise an event thread-safely.
I have a message despatch thread which looks somthing like.
while(_messages > 0){
Message msg;
// get next message
if (MessageDispatched != null)
MessageDispatched(this, new MessageDispatchedEventArgs(msg.Msg, msg.Params));
}
I can see that it may be posible for MessageDispatched to be come null after the check. from a MS blog I've seen:
var handler = MessageDispatched;
if (handler != null)
handler(this, new MessageDispatchedEventArgs(msg.Msg, msg.Params));
Which does stop the possibility of the reference becoming null after the check occurring. I'm wondering how to handle the case where the delegate is disposed (or even if it can?)
Should I just need to stick a try / catch around it, as its probably very rarely going to occur?
Edit
After reading answers I've considered making my class to handle this - quickly it looks something whats below, but I'm running into a few issues which make it not as clean as I want - maybe someone has an idea how to do that?
public class ThreadSafeEvent<TDelegate>
// where TDelegate : Delegate why is this a non allowed special case???
{
List<TDelegate> _delegates = new List<TDelegate>();
public void Subscribe(TDelegate #delegate)
{
lock (_delegates)
{
if (!_delegates.Contains(#delegate))
_delegates.Add(#delegate);
}
}
public void Unsubscibe(TDelegate #delegate)
{
lock (_delegates)
{
_delegates.Remove(#delegate);
}
}
// How to get signature from delegate?
public void Raise(params object[] _params)
{
lock (_delegates)
{
foreach (TDelegate wrappedDel in _delegates)
{
var del = wrappedDel as Delegate;
del.Method.Invoke (del.Target, _params);
}
}
}
}
The latter structure will make sure you won't get a null reference exception calling the handler on non-Itanium architectures.
However, it leads to another possible issue -- it's possible for a client that registered an event handler to have the handler called after it's been removed. The only way to prevent that is to serialize raising the event and registering the handler. However, if you do that, you have a potential deadlock situation.
In short, there are three potential classes of ways this can break -- I go with the way you've done it here (and MS recommends) and accept that it is possible for an event handler to get called after it is unregistered.
Please, check this out: Checking for null before event dispatching… thread safe?
Read this post from Eric Lippert : Events and Races

Categories

Resources