--> Friday .NET Trivia 1 - Impersonation Failure

Friday .NET Trivia 1

Stumbled across an interesting piece of code yesterday. Considering what we know about .NET reference and value types two questions regarding the snippet below :

  1. Would the snippet below compile?
  2. If it compiles how would it work and what would the result be?

Venture a guess before compiling :-)

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:   
   5:  namespace Adp.Snippets
   6:  {    
   7:      class Program
   8:      {
   9:          static Type Foo(Enum x)
  10:          {
  11:              return x.GetType();
  12:          }
  13:   
  14:          static void Main(string[] args)
  15:          {
  16:              DayOfWeek dow = DayOfWeek.Monday;
  17:              Type t = Foo(dow);
  18:   
  19:              Console.WriteLine(t);
  20:          }
  21:      }
  22:  }
 
 
del.icio.us tags:
 
Technorati tags:
Filed under: , , ,

Comments

# bkelly said:

I'll venture it will compile, and output 'DayOfWeek'.

Friday, November 17, 2006 11:07 AM
# Armand du Plessis said:

Thanks Brady! I should've placed more emphasis on the - in the event this compiles why/how would/can this work or why wouldn't it compile/work.

Friday, November 17, 2006 11:46 AM
# bkelly said:

OK, maybe I should have explained my reasoning, because I didn`t actually compile it.  

Only two immediate questions came to mind: Is dow an Enum, or DayOfWeek, and of course the answer is both.  My other question was whether Console.WriteLine would take a Type as an argument, but it has an overload with an Object parameter.

Friday, November 17, 2006 12:01 PM
# Armand du Plessis said:

Yeah, DayOfWeek is an Enum. I just used it as an example. You can substitute DayOfWeek with any other Enum.

Also Console.WriteLine would write out a Type just fine.

The snag in this snippet has to do with the Foo taking a valuetype Enum as a parameter and how value type parameters are usually treated...  In this case would the DayOfWeek type be preserved?

Friday, November 17, 2006 12:22 PM
# Ernst Kuschke said:

hmmm.... this looks familiar... :)

Friday, November 17, 2006 2:35 PM
# Armand du Plessis said:

Ernst, yep :-)

Brady, thanks for your comments. I just reread my post and outside of the context of the original problem it's not actually that interesting and this was definitely not the best of examples. And maybe so obvious you would probably ignore it and move on :-)

So the very abbreviated version: In the scenario where I ran into this I wasn't catering for the fact that the DayOfWeek/Enum value would be passed to the equivalent of Foo here in boxed form. (The calls were made through dynamic method invocation using reflection and also involved some native code)

First made the very wrong assumption that as the semantics for Value Types define that they should be sealed and derived directly from System.Enum or System.ValueType that System.Enum would be a value type. (For that assumption I shall wear a beard of shame for the rest of the year. Possibly the rest of my life :-)) This muddied the waters for me a little as, if my argument is in it's unboxed form and the function expects System.Enum which is a value type structure with no fields per spec, what was suppose to be passed/marshaled to this function for this argument!? The answer of course was that System.Enum is a reference type so the only value required for the argument is a pointer to the boxed enum. System.DayOfWeek in this case.

That in a round about way that was what  triggered this post and also which is why this was not really the best example.

In short, only the associated boxed type of the DateTime enum above is compatible with System.Enum which is a ref type as can be seen from the snippet below where the call is made:

The type of the argument is maintained as the System.Enum parameter is a reference type. The enum passed to it is passed in it's boxed form which preserves the Type data which is why this is completely valid and works.

 IL_0044:  ldloc.0

 IL_0045:  box        [mscorlib]System.DayOfWeek

 IL_004a:  call       class [mscorlib]System.Type Adp.Snippets.Program::Foo(class [mscorlib]System.Enum)

For a value type the call would've looked like :

 IL_0044:  ldloc.0

 IL_0045:  call       class [mscorlib]System.Type Adp.Snippets.Program::Foo(valuetype [mscorlib]System.DayOfWeek)

 

 

Friday, November 17, 2006 4:56 PM
# bkelly said:

"And maybe so obvious you would probably ignore it and move on :-)"

Yes, but I wanted to see what it was _really_ all about.

Monday, November 20, 2006 11:28 AM