API Review Process and Enums


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">One of my many jobs is to ensure the
platform managed APIs grow in a seamless and consistent way. style="mso-spacerun: yes">  In many ways we are victims of our own
success.  We have TONS of folks new
to managed code (and OO design) building new APIs for the platform (the .NET
Framework).  I have blogged before
about the two day class I gave every quarter to help train folks. style="mso-spacerun: yes">  But we also do extensive API
reviews.  In these reviews we focus
on simple scenarios and the shape of the APIs (rather than implementation
details).  o ns = "urn:schemas-microsoft-com:office:office" />


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Today we had a two hour review of
some new low level APIs the windows team is building. style="mso-spacerun: yes">  An interesting discussion point came
up.  I was “encouraging” the team to
make more frequent use of enums rather than magic constants. style="mso-spacerun: yes">  Such as: style="mso-spacerun: yes"> 
size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: Arial">Foo
(Colors.Red)
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> rather than face="Courier New" size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: Arial">Foo
(42) style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">. style="mso-spacerun: yes">  [The particular example from today’s
review was not nearly that blatant, but you get the idea]. style="mso-spacerun: yes">  The team justified their postion by
saying that using an enum was costly because an additional type is loaded (the
type for the enum). 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Now normally in the case I ask a
simple question: Have you measured it? 
Measurement is at the heart of perf work. style="mso-spacerun: yes">  Random speculation is not (which is why
I could never be a good perf guy;-)). 
In many cases the answer is no and in fact the api is only ever called as
part of a blocking network IO operation so the extra couple of milliseconds is
pretty much noise.  Or something
like that.  And in general I don’t
think that loading one additional type is a big thing to worry about even if it
was happening…


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">But this time I didn’t even have to
ask that.   You see, at
runtime, the CLR never loads the enum type. style="mso-spacerun: yes">  The compiler emits the constant value of
the enum.  (This is why you can
never change the value after you ship). 
Look at this simplistic example:


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">For the C#
code:


size=2>Foo
(Colors.Red);
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">The compiler
generates:


size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: Arial"> style="mso-spacerun: yes">  IL_0000: style="mso-spacerun: yes">  ldc.i4.s style="mso-spacerun: yes">   42


size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: Arial"> style="mso-spacerun: yes">  IL_0001: style="mso-spacerun: yes">  call style="mso-spacerun: yes">       void
ConsoleApplication1.Class1::Foo(valuetype ConsoleApplication1.Colors)


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Notice the first line we do a load
constant 42 instead of loading the Colors type and fishing out the Red
value.  Just as performant as if we
had passed in “42” but a LOT easier to understand. style="mso-spacerun: yes">  Note that the reference to
style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: Arial">ConsoleApplication1.Colors
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">in the type signature just specifies
the method to call, again, no additional types need to be
loaded.

Comments (4)

  1. I’m pretty sure the enum type will have to be loaded anyway. After all, it is part of the method signature.

  2. Here’s one more argument – it hurts the customer’s productivity. As an application developer, I’ve got plenty of goo that I have to remember as it is. I know that every time I use Foo(), I’ll have to stop, press F1, wait for the MSDN Library to load, look up the bloody Magic Number, then go back and type it in. And what about somebody trying to maintain my code? They’ll likely need to look up those values, too, in order to figure out what I was doing! And that doesn’t even consider times when the value of the Magic Number might have to change for some reason.
    Magic Numbers (and by extension Magic Strings) are bad. Period. Thank you for doing your part to stop them at the gate.

  3. Kevin Westhead says:

    Now if only the C# editor would automatically pop-up a list of enum values for enum parameters. <g>