Disassemblification

So, I’m working on these delegates, yeah?  And when I call the delegate to obtain a result and pass that into the parameters of Writeline, I have to use the “Invoke()” Method.  At first I was thinking this was due to my results being stored in a dictionary (as opposed to just calling it on its own, not as an element of a dictionary).  If I don’t use Invoke, it returns the object name.

Supposedly, you should be able to call a delegate using the same technique when you call a non-delegate method.  That is, just write “c.Add()” (versus “c.Add.Invoke()”)  I saw somewhere a mention of using “Func” as a way to call delegates, so I played with that.  There are two ways to call delegates like this:  Action and Func.  Action is basically what in Pascal would be called  “Procedure”.  It does something, but does not return a value (i.e. the return type is “void”).  Func, on the other hand, is what in Pascal would be called a Function – it returns a value.  You declare an action by using Action<T> (where T is the parameter being passed).  Func, on the other hand is via Func<T, TResult> where T is the parameter being passed and TResult is the return type.  Interestingly, when you have a void return type, you do not pass in “void” into the Func’s TResult parameter.  Instead, you just leave it off (i.e. it is an optional parameter).

In my case, the Calculator/Delegate has a signature of “void Calculator(int)”  So I would call Func<int> to indicate that this is a function that takes int as a parameter and returns nothing.  You can see this in the code below where I commented out the first Dictionary declaration.  In that case, you can see that where the line below it says “Calculator” I have “Func<int>, otherwise it’s all the same.

You’ll see that in the C# code posted that I first use Console.Writeline(menu[selection]), this will ultimately display the name of the object type itself, not the values that the object contains.  In this case, where I use “Calculator” it displays the string “Calculator” (as that is the object it is calling).

HAHAHA, I just realized that the problem is I was literally not calling it as a function, now that I’m looking at the code.  I am just calling the name of the object, but not adding the parens to indicate that I’m calling it as a function, hence it returning the name of the object type.  When I add the parens (without Invoke), it works just like I expect:
Console.WriteLine(menu[selection]); –> Console.WriteLine(menu[selection]()); <–THIS IS CORRECT – NOTE THE PARENS

(The code below is the wrong code)

Anyways, what I did to try to understand this better was use the utility ILDASM.EXE.  “Intermediate Language Disassembler” or something like that.  While I clearly didn’t grok the solution (I started this post before it hit me), I thought it insightful and figured I’d share it since it’s one more thing on my path to learning/understanding… (Commentary Continued beneath the C# code)

You’ll notice in particular the following:  The first call IL_007a clearly obtains the information on the Calculator Instance (I have to learn the difference between callvirt and call).  Here, you see that IL_007f then proceeds to call Writeline(object) (i.e. the object name – in this case “Calculator”).  This is what I was stumped on initially.  As you can see – it wasn’t calling the function itself, but rather passing in the object itself.  You can see the second time I try it using “Invoke()” it does the right thing on line IL_008b where it calls Calculator::Invoke(), thus invoking the calculator.

After testing my hypothesis, I ran it again, with the Parens added after the function name, and you can see that this time it properly called the function (that is, I added the Parens after the method name, stating that I’m invoking it, not just wanting to display the type of the object)…  Here you can see that what showed merely as “Writeline(object)” above on line 007f is now Calculator.Invoke(), as I was expecting all along.

It makes obvious sense now when I look at it, but it certainly seemed frustrating at first.  The nice thing about this is that it means you have reflection – you can “reflect” upon not just your output, but upon the code itself, you have access to information about the program as its running – you can gain information about the types and classes you’re dealing with, from the program itself.  It’s like it’s looking in a mirror and seeing itself and the parts of itself.  Hence the term “reflection” (don’t quote me on this as a technical reason, I’m just figuring that’s the analogy).

There are, I am to understand via various forum posts, even better tools to deal with disassembly and looking at the IL code – LinqPad is oneof the more popular ones, ILSpy is also another one I’ve heard of.  If you’re curious about the guts of .NET and want to see how the sausage is made on a lower level, this is a fun way to do so.  Wikipedia has a nice reference of all the assembly instruction codes (ldloc, callvirt, etc…)  Google it if you’re curious.

Below is the original full IL disassembly (showing both the wrong and the correct ways of calling the invoke (the bold of which I repasted above, but I leave the full disassembly here for posterity’s sake)

 

Playing with sharp Cs

Here’s the code I wrote today…
Just for some learninatin’…  Want to work on understanding Delegates and ultimately Events.  It’s funny – as much as I rip on JS, the fact is, due to the primacy of its event-driven architecture, events are easier to grok there.  I mean, I understand the concepts of events in C# and delegates as well… But to implement it takes a better understanding than I currently have.  Theory is one thing, praxis is another.

For instance, I tried to use a switch statement where I assigned the proper Number.Function() to the delegate (i.e. pointer to the function)  It was something like (see below for the complete working code and definitions of number and calculator):

But unfortunately, because I was assigning C inside the switch statement it was only staying local to that block (ugh) – I mean I get it – scope and all. (kept telling me I was trying to use an uninitialized variable). So looking some more I also remembered one of the reasons I would want to use this is for firing weapons. You have an array of functions and then hit a generic “fire” method, which then calls up the currently loaded weapon firing system. So instead of having a bunch of switch cases where I have to go through and write a new case each time I have a new weapon, all I would have to do is add a new function to the list (as seen d[x] = functionName();) which is a lot easier to maintain in the long run, more compact and easier to read.

In some ways it feels slightly frustrating to work on such small projects, as if I’m wasting time, the fact is – if I’m going to understand things, it’s best to work in a space I can grok them here and now, rather than trying to dive into a large complex program in a system I’ve not programmed in before and then try to tie it all together.  Believe me, just doing this took a couple hours and it shouldn’t have.  But that’s because I didn’t quite grok how to do this (obviously).  Now I do, which was the whole point of this exercise.

The next trick will be trying to figure out the event system.  Again – I have the basic concepts down and I’ve monkeyed with it a little in the past, but I’d really really really like to get it stuck in my head, because there is a lot of power in that, and it’s really imperative for moving on with my game programming down the line (it will certainly make code more manageable and understandable, and less spaghetti-like when I can just fire an event and have something watching it go “BAM got it!” and then execute what it needs to, instead of having to externally call that method from another function (which is where the “spaghetti” part comes in, weaving all these systems in a way that’s messy… not good).  In other words, trying to architect the software better.  That requires deeper understanding of these features.  In the same way “GOTO considered harmful” (leading to spaghetti code, and bad engineering) and functions/methods/classes helped to tame that, it’s still possible to create more spaghetti and events and delegates are one more feature to reduce some of that.

Unfortunately in C#, the way the language was designed, it still feels like spaghetti to me.  They’ve refined things to make it easier, but there’s all this extra… linkage that seems to go on that’s extra cruft.  I think part of my problem is they talk about subscribers and publishers, and IIRC, my mental model always gets shit backwards on who is the subscriber, who is the publisher, what is the delegate and what is the method being called and getting those terms linked up is vital so I can really get the best mental model of how it operates.

In things like JS and Python, it seems a little more nimble and easy to do stuff like that.

This isn’t necessarily bad, because C# is supposed to be a heavy duty language (not that JS and Python don’t do some heavy duty things themselves!), but there is a lot more enforcement of rules and patterns due to the nature of the language, I think — could I get more vague?)

Overall I still have a fondness for C#, but its ties to the Java style history definitely show and it slightly annoys me.
On the other hand, C# is HELLA easier to get compiling and working on my system than Java ever was.  Even years later, I had problems with “classpaths” and setting the dev environment up properly with Java (the other night, I actually found an old post of mine from comp.lang.java where I was asking about the classpath).  C# just fucking works.  Period.  That in itself is one great thing.

The mental model I have of C# is easier than Java and it’s .jar archive/formats/namespaces…. “com.fuckyoudipshits.appname.blahalahblahb”  C# has namespaces, and I’m sure it’s down there if I really needed to mess with it, but so far, it’s been easy to just dive right in and not fuck with that sorta thing.

They have something called Assemblies which is sort of like, IIRC, your DLLs, your application code, etc. all linked together.  Then you can have various namespaces in the assembly so you can a good separation of concerns and access across the assembly and thus better protection in that regard.  Anyways, it’s kinda cool and I can understand the model better than I have with Java.  I admit I haven’t done as much with Java as I have with C#, but neither have I done a lot of “proper” C# either.  Most of it’s been Unity, which is stuck on 2.6 of Mono (I think they might have a newer version now that Unity 5 is out, though I’m not sure)…   and that means it’s about .NET 2.0.  To give you an idea of where we’re at with .NET officially, they’re at 4.5, and are working on 5.0