Lecture thumbnail 0:01 / 9:53 Hello and welcome to another screencast on some of the more complicated features of the social programming
language.
And in this lesson we’re going to talk about duct taping and about how you can create mix ins which
leverage duck typing.
So there’s two things that we need to discuss.
What is duck typing and what is it mixing?
So let’s discuss the first thing.
So duck typing is basically this idea that you can call a method from a particular class or Darknet
can call a method from a particular class.
Even if that method isn’t part of some interface, the dot net expects it just expects the name of the
method.
That’s it.
So there are two very well-known examples of duck typing in net.
So the first one is get a numerator.
So get the numerator is a method that can be found in a class.
And if that net finds this a method, it can call for each on an instance of this class, even if the
class doesn’t implemented the them.
So you can implement on them or both.
But even if you don’t implementing them or all of the but you have the get the numerator method, then
you can eliminate a particular class.
So this is one example.
The other example is of course this both.
So essentially when you have a using statement, so using var food, for example, it doesn’t really
matter if that variable is disposable or not.
So yeah, we do have the disposable interface, but you don’t have to use it.
And in actual fact, there are plenty of cases where you cannot use it.
Let me show you a very simple example.
Let’s suppose you have a ref struct ref struct fu which has a public void dispose which does disposing.
Okay, so ref structs cannot implement interfaces.
You cannot say I disposable here, this is not legal, but you can have your dispose method and you
can use this dispose method.
Let me show you.
So if I say something like using var fu equals new form and then if I actually run this program, let’s
see what happens.
Okay.
And as you can see, it says disposing food.
So we essentially invoked this method even though we didn’t explicitly implement the high disposable
interface.
And the same goes for for each enumerations.
So this is great.
This is something that we can leverage already.
Meaning, if you want your class to be enumerable, somehow you don’t have to have enumerable.
You just do the get the numerator and yield the elements from there.
And that’s it.
But the question is, can we provide this functionality or this functionality as mixing functionality?
So let’s talk about what mix ins are.
So essentially, mix ins are ways of adding additional functionality to a class.
And typically, if we’re talking about C++ in C++ because of multiple inheritance, you can add some
functionality on the side.
So if you have some class called food and you have some class called bar which inherits from food,
then in C++, what you can do is you can make an additional class and then you can have some extra functionality
here.
And when necessary you can just say additional here like so.
So in C++, this is legal and in a dot net, this is obviously illegal because we don’t have support
for multiple inheritance.
So typically when you want to add functionality to the class, Nixons are implemented in different ways.
So one of the most obvious ways is of course extension methods.
So if you want bar to have just additional behavior as you would add an extension method for this behavior,
but it’s very limited because sometimes you want to have fields, for example.
So if you want fields, then it becomes really tricky because you end up having something like a conditional
weak table.
And this is a whole separate discussion that is outside the scope of what we’re discussing here, because
what we’re discussing is specifically these two interfaces, the enumerable interface and the of what
interface?
And it turns out that it’s possible to have mixed in implementations of these interfaces that can be
added to an actual class.
Now, these are going to be slightly technical demos.
So first of all, let me show you how you can get how you can get I disposable.
So let’s suppose that you want to have some action happen whenever an object gets disposed.
So for example here, what I’ll do is I’ll make an interface which will call I my disposable interface
in my disposable and I’m going to inherit this from my disposable like.
So now what I can do here is I can go ahead and I can override the disposal method explicitly.
So notice it’s saying not void dispose but void I disposable dispose.
And here I can, for example, say, oh, I’m disposing such in such a type.
Now, of course, if I want to specify that type, I would maybe added here and here I can say something
like disposing, disposing a particular type.
So type of t dot name.
So this is something that we can leverage in an actual class.
So let’s suppose I have a class or indeed, you know, struct, but let’s go with a class, let’s call
it my class.
Now what I can do is I could say my class is I disposable of my class.
Now we go now what is the viability of this?
The viability of this?
Is that what it’s actually it should be my disposal.
Now we go.
So in actual fact, what we’ve now done is we’ve taken this functionality, the functionality of the
dispose method, and we have given it to my class.
Now, of course, you cannot say like if I make my class, so if I say var MSI equals new my class,
like so I cannot call MSI dispose.
So this is not going to work.
MSI disposal is not explicitly available because you have to cast it to I my disposable.
But what because of duct typing the dot net framework, the seashell compiler is actually going to find
it anyway.
Which means if I say using var MSI, it’s still going to find that method and it’s still going to invoke
that method.
Let me actually run this just so you can see that it does in fact workings here.
As you can see, it says disposing my class.
Okay.
So the same thing works for I enumerable.
So let me show you how this works.
And it’s only slightly more complicated than this.
Essentially what you do is let’s suppose you want to have an interface for scalar objects where if you
enumerate an object, it just gives you that one instance of the object.
How do you do it?
Well, you make an interface.
Interface I scalar of t which.
Implements innumerable of tea like soap.
And then once again, you use your favorite ID to override the members, which are get the numerator
and get the numerator.
So one is generic, one is non generic.
The one that is non generic is easy because here you just return the ordinary, the generic variety
so we can even turn it into an expression body.
So from this you return this, which is on this method right here and here.
If you want to make it a scalar with simply you would return this.
Okay?
So once again we need to cast it to t by the way, once again, this is functionality that is now reusable,
meaning that this makes an interface which leverages duct typing can be used here.
So here I can say I scaler of my class and that’s all there is to it.
Now to test this, I’m going to just have some sort of two string implementation which returns my class
like so and then we can actually go ahead and test this.
So I’m going to save arms equals new my class and for each of our acts in MSI, I can actually see w
x.
So if we now run this.
We should get just one line.
And here we go.
We get the line saying my class.
Okay, so this is how you can use duct typing on an I enumerable.
So once again, the funny thing here is that even though my class is in fact I enumerable it’s not accessible
directly, meaning the members of I enumerable which are being defined here and here.
They are not directly accessible.
You have to cast it to a an appropriate interface.
But because the interface is used behind the scenes through a duck typing, you effectively get to use
all of the implementations here.
So you effectively have a functional mixing.
So you have a mix in where you’re using instead of using extension methods because you couldn’t define
this in an extension method.
And the funny thing is you couldn’t just go ahead and give the class an extension called get a numerator
that is not going to work.
But this approach, the approach where you use default interface members and you mix them into the class
that you’re working with and then use duct typing to leverage this functionality.
This approach does in fact work, and I know it’s a very nice thing to have and mixing I disposable
or mixing I enumerable, but the options are there if you need them.
Stop Play Play Play Play Play Play information alert