Lecture thumbnail 0:00 / 0:00 In the example that we’ve considered for the null object, we have a very simple interface called Ilog

with just two members in it.

Now imagine if you want to build a null log for an interface with 100 methods in it.

How would you do it?

Well, the answer is that you would probably still go ahead and do it in this kind of static way and

suddenly Resharper will generate the signatures for you.

However, there is an alternative.

There is an alternative using the DLR.

Now, as soon as I tell you that the alternative is using DLR, you should in your head realize that

the performance hit is going to be significant.

So if you’re using the DLR to build a dynamic Null object, you’re immediately paying the price of dynamic

construction and invocations, which are dynamic.

But on the other hand, what you will preserve is you will preserve the Ilog interface.

And this is possible using a special library.

So in this case, what I’m using is a library called impromptu interface.

You can find it on Nugget.

It’s a library that you can install and it uses the DLR to make sure that your dynamic object acts as

if it has a particular interface, even though it doesn’t really implement that interface.

So in this case, we need some sort of object which acts as an eye log and does absolutely nothing at

all, whatever you ask of it.

So how do we make one?

Well, it’s going to be as follows.

We’re going to have a public class null of T and it’s going to be a dynamic object.

So it’s going to be a dynamic object.

We’ll also put a constraint on T that T is we’re seeing a class here, but really T has to be an interface.

We may as well indicate it in the type argument t interface.

There we go.

Now we’re being more honest at least.

So this object is going to have a single property called instance.

And I don’t really know if we want to make it a singleton or not.

I’m not going to make it a singleton, but it’s going to be a property which returns an instance of

this particular type.

So essentially what I’m going to do is I’m going to have a public static t interface instance.

Notice it’s returning T interface.

So we’re returning an eye log, for example.

Now how can we get an eye log considering that this isn’t even a log, this isn’t a logging construct,

this inherits from dynamic object.

It doesn’t implement log.

So how can we get an eye log?

Well, the answer is that you return a new object of the current type.

So that would be null of t interface.

Of course, if you were to just return this object, then that’s not legal because null of t interface

does not convert to t interface.

But then we do something interesting.

We use the impromptu interface package to act like.

So we tell the object that we’ve just constructed null of the interface to act as if it had the interface

t interface implemented.

And that is a dynamic construct.

So here once again I can convert this to an expression body which would be a bit too big.

And then of course all we have to do is we have to make sure that every call on this null object, which

by the way, exposes itself as having that particular interface, whatever interface you want.

Really, we need to make sure that any invocations do absolutely nothing at all.

So in this case, if we go into overriding members, the one that we’re interested in for our case is

try invoke member.

So that’s what we’re going to override.

And here the boolean that is returned from this member indicates whether the operation actually went

okay or not.

So I’m going to return true here.

But in addition, we have to set the out parameter.

If you look right here, there is an out object result, and that is the idea that if somebody called

a method, for example, then you want to return whatever this method was returning.

So in our case, we want to default to the value that would be returned.

So for example, if a method returns an int, we want to return a default constructed end.

So the way this is done is by saying result equals and then we can just do Activator.createinstance

our favorite factory for types.

And here we specify the type as binder dot return type.

So we just make a default constructed object of the return type.

Now, this can also be problematic.

If the type you’re returning doesn’t have a default constructor, then it’s going to go wrong.

But I’m making the assumption here that all of our types are like this.

And yes, by the way, it does return.

It does work okay with void methods as well.

So there is no problem here.

So what we just built is a piece of hackery which allows us to make a dynamic object which does absolutely

nothing at all when you invoke one of its members, but it exposes itself not as a dynamic object,

but as an object of the correct interface.

So let’s actually use this and let’s see how it all goes.

So I’m going to say var log equals and then I want to make a null.

I log null, I log instance and this way I’ve just made a null I log and then I can use this in the

bank accounts of var equals new bank account.

And I can specify the log here and then once again I can do var deposit 100 like so.

And this is perfectly fine.

And by the way, look at log dot.

So log is a completely legitimate I log.

It has methods like info and warn and you can call them with whatever and it doesn’t really matter.

All of those will be consumed.

You will assign default result if you need a result and it’s going to return.

True.

So nothing will happen as you call log.info.

So let’s execute this.

Hopefully we don’t see anything at all.

Hopefully no exceptions.

As you can see, we’re not getting anything because we’re using a null object.

So this is an alternative implementation and I hope you realize that there is a performance hit to this

because you’re using the DLR to actually construct the object.

So whenever you make those invocations, they’re going to be very expensive.

These invocations are going to be a lot more expensive than if you were just calling a method normally.

So this is probably okay for testing, okay for prototyping and exploring the API and not so good for

production code.

But still this option is available if you need it.