Every operator overload that we use in C #, gets converted to a function call in IL. The
Overloaded > operator translates into the function op_GreaterThan and a + gets converted
to op_addition etc. In the first program of this chapter, we have overloaded the + operator
In class yyy to facilitate adding of the yyy objects.
While using the plus (+) operator on the YYY objects, C # is aware this IL does not
Support operator overloading. Therefore, it creates a function called op_addition in the
Class yyy.
Thus, operator overloading gets represented as a mere function call. The rest of the code is
Easy-for-you-figure-out.
In IL, there are no rule stating that if the > operator are overloaded, then the < operator also
Have to is overloaded. These rules is imposed by the C # compiler, and not by il since, IL
Does the concept of overloading at all.
the C # compiler is extremely intelligent. whenever a yyy object have to is converted to a
string, it first checks for the presence of a operator called string in the class yyy. I F it
exists, it calls that operator.
the operator named string is a predefined data type in C #. Hence, it is converted into the
operator op_implicit. This operator takes a yyy object as a parameter. It returns a string of
the stack for the WriteLine function. The ToString function is not called.
c# would generate an error if your alter even a single parameter to the operator string, BU T
such is not a case with IL as it does not support operator overloading and Conver sions
In the C # code above, we have dispensed with the operator string and instead, which have used
The ToString function. As usual, we put the object a on the stack. In the IL code given
Earlier, due to the presence of operator overloads in the C # code, the function op_implicit
was called. In this case, since there is no operator overloads, the object reference to object
A is simply put on the stack. In class yyy, even though, the function ToString are not
Explicitly called, the function does get executed.
Since The ToString is virtual in the class Object, at run time, the ToString function is called
From the class yyy, instead of being called from the class Object. this was due to the concept
of a vtable, where all virtual function addresses reside.
If the word virtual is removed from the function, the ToString function gets called from the
Class Object instead of the class yyy
In the above code, we had cast a yyy object into a string using a explicit cast. IL does not
Understand C # keywords like implicit or explicit. It converts the cast to an actual function
such as op_explicit or op_implicit. Thus writing a C # compiler requires a lot of grey matter.
In the code above, we were not creating a object that was an instance of Class yyy. Instead,
We is simply initializing it to a numeric value of 10. This results in a call to the implicit
Operator YYY, which takes an int value as a parameter and creates a Yyy object.
The IL code does not understand any of this. It simply calls the relevant operator, which in
This was op_implicit, with an int value. It is the responsibility of this function to create
An object, which is an instance of Class yyy. We are, in effect, creating, and locals.
YYY, and initializing them to the new yyy as object on the stack. Finally It value,10, is put
On the stack.
In the above code, we have created the objects, A and B, which is instances of a class yyy.
We have employed the overloaded operators & and && to determine as to how IL
Handles them internally. If we can grasp the intricacies of IL, our understanding of C # would
become so much better. Maybe, a programmer should is allowed to program in C # only if
He/she has learnt IL.
The DUP operator duplicates the value present at the top of the stack. It is the
Local v_0. All occurences of && and & in the C # code is replaced by the functions
Op_false and op_BitwiseAnd respectively, on conversion to IL code.
The op_false operator returns either TRUE or False.
? If It returns True, then the answer is TRUE, and the rest of the condition are not
Checked. This is what the code is short-circuited. We simply jump past code
To is executed.
? If It returns FALSE, the & operator gets called. This operator gets converted to
op_BitwiseAnd. In order to enhance the efficiency, the objects were already present
The stack for the op_BitwiseAnd operator to act upon.
You'll be appreciate this IL makes our understanding of abstract concepts of C # much
Easier to understand.
In IL, the object m is a local named v_0 of type System.Type.in C #, the TypeOf keyword
returns a Type object, but in IL, a large number of steps has to is executed to achieve the
same result.
? Firstly, a type is placed on the stack using the instruction Ldtoken. This loads a token
That represents a type or a field or a method.
? next, the function gettypefromhandle is called this picks up a token, i.e. a
structure or value class from the stack.
the function thereafter returns a type object representing a type , which in the
is an int. This was stored in the local v_0 and then again loaded on the stack.
? next, the function get_fullname is called. The function isn't called FullName but
Get_fullname as it's a property. The returns a string on the stack, which is
displayed using the WriteLine function.
The keyword is lets us determine the data type of a object at Run-time. Thus the IS
Keyword of C # has a equivalent instruction in IL. We is passing a zzz like object and an
The object is a instance of class object to the function ABC. This function demotes every
Parameter it receives to a class object, but the WAS keyword is intelligent enough to know
That the run time data type can is of a type other than an object. Thus, it returns TRUE for
The Z object, but not for the A object.
The assembler code in Main or Vijay remains the same. The relevant source code is
Present in the function ABC.
? The instruction Ldarg.1 pushes the value of parameter 1 onto the stack. The data type
Of this parameter is Object.
? Next, the instruction Isinst is called. The type with which we want to compare the
Object on the stack was passed as a parameter to Isinst. This instruction determines the
data type of the value present on The stack.
if the type of the isint instruction matches what's already there on the stack, the
object re Mains on the stack. If It does not match, a NULL was placed on the stack.
the brfalse instruction executes the jump to a label if the result was TRUE in the Il
Code.
The keyword as is similar to the. The objects has been placed on the stack and the
Function ABC is called. This function requires a object on the stack. The type of the
Variable a have to is converted from int to an Object. The isinst instruction takes value at
The top of the stack and converts it into the data type specified. If It is a unable to doing so, it
Puts a NULL on the stack.
In the second call, on the stack, a string was obtained for the WriteLine function. Since an
Int32 value cannot be converted to a string, a NULL value is placed on the stack. Hence
The WriteLine function displays a blank line.
All pointers in C # has a size of 4 bytes each. The sizeof keyword is a instruction in IL
That's returns the size of the variable that's passed as a parameter to it. It can only be used
On a value of type variable, not on a reference type.
In C # We use the modifier unsafe while introducing pointers. This modifier does not exist
In IL, as il regards everything as unsafe. Note that a byte in C # is converted to an int8 in
IL.
C # to IL 5 Operator overloading (operator overloading)