What’s the difference between "as" and "cast" operators?


Most people will tell you that the difference between “(Alpha) bravo” and “bravo as Alpha” is that the former throws an exception if the conversion fails, whereas the latter returns null. Though this is correct, and this is the most obvious difference, it’s not the only difference. There are pitfalls to watch out for here.

First off, since the result of the “as” operator can be null, the resulting type has to be one that takes a null value: either a reference type or a nullable value type. You cannot do “as int”, that doesn’t make any sense. If the argument isn’t an int, then what should the return value be? The type of the “as” expression is always the named type so it needs to be a type that can take a null.

Second, the cast operator, as I’ve discussed before, is a strange beast. It means two contradictory things: “check to see if this object really is of this type, throw if it is not” and “this object is not of the given type; find me an equivalent value that belongs to the given type”. The latter meaning of the cast operator is not shared by the “as” operator. If you say

short s = (short)123;
int? i = s as int?;

then you’re out of luck. The “as” operator will not make the representation-changing conversions from short to nullable int like the cast operator would. Similarly, if you have class Alpha and unrelated class Bravo, with a user-defined conversion from Bravo to Alpha, then “(Alpha) bravo” will run the user-defined conversion, but “bravo as Alpha” will not. The “as” operator only considers reference, boxing and unboxing conversions.

And finally, of course the use cases of the two operators are superficially similar, but semantically quite different. A cast communicates to the reader “I am certain that this conversion is legal and I am willing to take a runtime exception if I’m wrong”. The “as” operator communicates “I don’t know if this conversion is legal or not; we’re going to give it a try and see how it goes”.

Comments (36)

  1. DRBlaise says:

    Very interesting post as always.

    I did some testing and it also appears the "as" operator handles one more special case: Converting from a ValueType to Nullable<T>.  (Or is this considered a boxing and unboxing conversion)  The code below worked for me:

    int i = 1;

    int? n = i as int?;

  2. Voo says:

    Ok since I’m not a C# programmer: Just curious where would you want to use the “as” operator instead of an explicit cast?

    I think I covered that in the article, but to sum up, here are two ways to think about it.

    First, “as” means “I expect that sometimes this will not succeed, give me null in those cases”. A cast means “I expect that this will always succeed; if I am wrong, then please crash the program”.

    Second, “as” means “I want to know what this object *really is*, not what it is convertible to by some representation-changing specially-defined conversion rule. A cast means “convert this thing using whatever crazy mechanism you need to do to make it work.”

    Choose the one that matches the meaning you intend to implement. — Eric

    I mean as we all know (thanks to this blog at least 😉 ) things get implemented because many people want/need them and it’s worth the cost of implementation, or is the as operator just a byproduct of something else?

     

  3. TheCPUWizard says:

    @Voo… One case is when it MIGHT be of the type:

    class Animal;

    class Dog : Animal {}

    class Cat : Animal {}

    Animal a = new Dog();

    Cat c = a as Cat;

    One "anti-pattern" to watch out foo (I see it far too often) is:

    if (a is T)

    {

      T t = a as T;

    }

    or even

    if (a is T)

    {

      T t = (T) a;

    }

    BOTH are better performed by a single invocation of "as" and a null check.

  4. Pavel Minaev [MSFT] says:

    Another anti-pattern that I often see is this:

     (x as T).Foo()

    Apparently people write it because they consider "as" to be more "aesthetically pleasing" than cast with its extra parentheses (and I can’t blame that for it, to be honest – C cast syntax is one of the worst parts of the language, second only to pointer/array declarators), and ignore other implications, such as the intended semantics of the cast.

  5. @TheCPUWizard…

    You are quite correct, but if you start with…

    if (o is SomeClass)

    {

        SomeClass sc = o as SomeClass;

        /* Use sc */

    }

    else if (o is SomeOtherClass)

    {

        SomeOtherClass soc = o as SomeOtherClass;

       /* Use soc */

    }

    else /* etc */

    To rewrite this using as instead doesn’t look quite so tidy. Maybe you could put the as operation and assignment inside the IF condition and then check the value returned by the assignment operator, but that doesn’t look so nice.

    Besides, I would hope that a good compiler would optimise is-followed-by-as into a single operation anyway. No idea if any do.

  6. @Pavel Minaev [MSFT]

    Totally agree. I kinda wish C# could do (X castas Y) to be exactly equivilent to ((Y)X), but that would mean a new reserved word.

  7. Mike says:

    The ‘as’ operator seems to be one of the most abused operators at my workplace. When asked, most devs say they use it "because it looks better." What often results, however, is that improper casts aren’t caught until they try to use the null reference later on in the code. Consider this example:

    var someObject = (object)new SomeType();

    <bunch of code>

    var A = someObject as ADifferentType;

    var B = (ADifferentType)someObject;

    <whole bunch of code>

    <whole bunch of code>

    <whole bunch of code>

    A.DoSomething();

    B.DoSomething();

    Assume here that ADifferentType does NOT derive from SomeType. In this example, the ‘as’ operator sets A to null because it’s not the proper type. However you don’t catch that until much later in the code (and in the extreme case, in an entirely different method), where you try to reference it. This makes debugging difficult. On the other hand, when we try to direct cast to variable B, we get an exception immediately and our bug is pinpointed on the spot.

    In the world of generics (and therefore mostly type safe code), I find the ‘as’ operator is almost never appropriate. I have a standing rule with my devs that if they find themselves tempted to use ‘as’, come down and see me because, except for a few rare circumstances, it almost always indicates an architectural problem.

  8. TheCPUWizard says:

    @Bill…. As of 2010 Beta 1, the compiler (neither C# nor JIT) perofrms that type of operation, and these can be long running operations. Your code effectively is:

    if ((o as SomeClass) != null)

    {

       SomeClass sc = o as SomeClass;

    }

    Would you EVER code that directly???

    @Mike…If you consider the use of RTTI (Runtime Type Identification) based logic to be an "architectural problem", then I agree with your post. However I consider it (RTTI) to be avaluable tool.  If you are going to "restrict" the use of "as", then IMPO, to be consistant you must place the EXACT same restraints on "is".

  9. @TheCPUWizard

    "As of 2010 Beta 1, the compiler (neither C# nor JIT) perofrms that type of operation,"

    (Assuming "that type of operation" is refering to compilers optimising is-then-as.)

    That’s a pity I think. It seems a simple optimisation, but I’ve never written a compiler so I can’t really say. The fact we’re having this conversation at all would indicate its a common enough thing that programmers do.

    "Would you EVER code that directly???"

    No, I wouldn’t. I’d use the is operator instead. It looks simple enough with one if operation on its own, but I’m thinking more of a long else-if chain, and we only get the if-condition to do our thing.

    What’s the alternative to my sample code in my earlier comment? I guess this…

    SomeClass sc;

    SomeOtherClass soc;

    /* 20 more. */

    if ((sc = o as SomeClass) != null)

    {   /* Use sc */  }

    else if ((soc = o as SomeOtherClass) != null)

    {  /* Use soc. */  }

    /* 20 More. */

    How much CPU time are we saving with this version? (vs the time spent going "what the …. is going on here?" when some tries to review my code.)

    If this (below) were legal, or the code were in a tight loop, I might be persuded.

    if ((SomeClass sc = o as SomeClass) != null) { }

  10. TheCPUWizard says:

    @Bill – compare the situation to a method call. Multiple calls to the same method in sequence do not (and should not) be automatically reduced into a single one.

    As far as your second sample. I would NEVER code a chain like that. I would calculate the type ONCE and do a switch against constant values.

    As far as the timing goes, I recently was debugging code similar to the following:

    foreach (var o in coll)

    {

      T t = o as T;

      if (t != null)

        t.Property = Value;

    }

    The "as" took 95% of the processing time (ie 20x the time taken to assign the property…

  11. Jay Bazuzi says:

    Not that you asked…

    I think of casts a mild code smell, much like comments. When I have one, I want to take a minute to ask whether there’s another design that wouldn’t need it, and whether that design is attractive in other ways.

    In C#, comments are easy to find, thanks to their unique and obvious syntax.

    If C# had chosen a syntax like C++’s dynamic_cast<> operator, it would be easy to find them, but it didn’t. C# casts are not syntactically obvious, since parens are used for a lot of things.  At least ‘is’ and ‘as’ are easy to find, but casts are not, and it’s too late to change the language to help.

    My wish (request?) is that the C# tools of the future make it easy to find casts, so I can give them that extra scrutiny.

  12. Mark says:

    Another blog I learned something from.  I always assumed that (Cast) versus as were identical save for the difference when a failure occurred (in the same way that you have int.Parse + int.TryParse).

    Mike: Well said.  I also see a lot of similar things.  

    It’s especially insidious when people speculatively cast something and then hand the reference off to another method to deal with it.  You get a failure down the line and that failure is now potentially a long ways away from the site of the cast, plus it’s a NullRef instead of an InvalidCastException.  Even more galling is the fact that tools like ReSharper tell you that this is the case, yet people still ignore the warnings.

    I do agree that casting in C# is particularly ugly, though.  

    ((Blah)otherblah).SomeMethod(); is much harder to read and type compared to (otherblah as Blah).SomeMethod();  

    If anything, the direct cast should’ve been easier to write instead of the speculative cast via "as".  Like Mike said, I see it abused quite a lot.  I also agree that casting often reeks of a design problem.  Sometimes it’s unavoidable, but most of the time it’s indicative of a problem in the design.  

  13. Simon Buchan says:

    So noone else here has written an object.Cast<T>() extension method? "foo.Cast<Bar>().Baz()" is pretty easy to read to me. I also use object.IfType<T>(Action<T>) instead of as, which I find easier to read as well, but then again, I also prefer "enumerable.Each(x => Console.WriteLine(x))", so I’m probably not the best person to ask here…

  14. Jon Skeet says:

    @Simon Buchan: Given that there’s Enumerable.Cast<T> in LINQ, I don’t think it’s a good idea to create another extension method with the same name. It won’t be clear what’s going on in all situations.

  15. tobi says:

    How do the casting operators behave when they encounter a null reference?

  16. configurator says:

    tobi: A null can be cast with () to any reference type for which the code compiles. With as, it obviously returns null as well. If you are casting with () to a non-nullable value type, you’d get an exception.

  17. Aaron G says:

    I’m curious why “(foo as Bar).Baz()” is considered an anti-pattern.  Is it just because of the potential for a null-reference exception?

    No. You’re looking at this too narrowly. — Eric

    I’ve used this from time to time in combination with the “as” operator, for example:

    if (x is Foo) { (x as Foo).M(); }
    else if (x is Bar) { (x as Bar).N(); }
    else if (x is Baz) { (x as Baz).P(); }
    else { throw new NotImplementedException(); }

    Obviously it doesn’t happen often, but if the base class doesn’t have a discriminator property then it’s kind of the only way to deal with class hierarchies.

    Given that we’ve already validated x to be a Foo, Bar, whatever, then there’s no way to get a null reference inside the conditional. Same goes with a class that’s expected to implement some, but not all, of some set of interfaces – just change (Foo, Bar, Baz) to (IFoo, IBar, IBaz).

    I suppose I could write it like:

    IFoo foo = x as IFoo;
    if (foo != null) { foo.M(); return; }
    IBar bar = x as IBar;
    if (bar != null) { bar.N(); return; }

    …and so on, and I guess this is the most efficient and “correct” way, but even this oversimplified example gives me a headache to look at.  It’s not about aesthetics, not really, it’s just that the way it’s structured doesn’t even come close to expressing its real intent.  The first version clearly presents itself as “x is going to be exactly one of these things, and depending on which one it is, we have to do something different with it.”

    And there’s the broader problem right there. — Eric

    Is there a better way that I’m not aware of?

    You’re looking at the problem at the wrong level. The problem isn’t that the result might be null. The problem is that the type check is needed in the first place. Let’s make your example slightly less abstract:

    void Frob(Animal x) {
    if (x is Mammal) { (x as Dog).Bark(); }
    else if (x is Mammal) { (x as Mammal).Milk(); }
    else if (x is Butterfly) { (x as Baz).FlutterBy(); }
    else { throw new NotImplementedException(); }

    What do we conclude about this? I conclude that the author of this method has no clear idea what “Frob” means for any given Animal! The fact that you have an Animal but then need to do something special depending on whether its a Dog, Mammal or Butterfly indicates a design problem in the Frob method’s class; Frob probably should actually be three separate methods. It’s also deeply unfortunate that Frob provides a trap for the unwary caller. Frob’s contract looks like “I can handle any animal”, but clearly it cannot. Again, this is evidence that Frob needs to be several different methods.

    Another tack: notice that essentially what I’m doing here is simulating a virtual call on a non-existent Frob method on Animal. We could therefore also conclude that some virtual method is missing from Animal, again indicating a potential design problem, this time with the class hierarchy. But either way, something here is messed up. — Eric

  18. DRBlaise says:

    Eric — I have to agree with your response to Aaron that this type of pattern is a potential design problem.  But often this situation is unavoidable.  Often we do not have the option to go back and add a virtual method to the base class and implement them in the sub classes.  Extending your Animal example, what do you do when you need to add a new method "void TagAndRelease()" but are unable to modify class Animal and all it’s sub classes?  Each sub class needs to have a different implementation.

    With version 3.5 of C# and before, the only option I see is using the "is" and "as" operators with lots of "if" statements like others have discussed.  Does anyone know another way?

    With version 4.0 of C# the new "dynamic" functionality could be used if you create a specific method for each sub class.

    void TagAndRelease(Animal x) { TagAndReleaseSpecific((dynamic) x); }

    void TagAndReleaseSpecific(Dog x) { // Dog specific logic }

    void TagAndReleaseSpecific(Butterfly x) { // Bufferfly specific logic }

    etc…

  19. empi says:

    I wanted to ask why as operator was implemented this way? Before reading this post, I was quite sure that as opeator behaves the same way as normal casting does, but instead of exception I get null.

    Using as operator only for types that may be null is also clear.  

    However, I don’t understand why as operator "will not make the representation-changing conversions". I think most people expect that.

    Another great post!

  20. Robert says:

    CAST: Try to force something to (be something that it might already be) or (force it to be something similar), ..if not possible, throw an exception.

    AS: Declare something to be something, if it is not of type something, do not CAST it, and default to NULL.

    You could maybe compare CAST & AS to <T>.Parse() & <T>.TryParse() ..one throws an exception, the other defaults to a value.

  21. Pavel Minaev [MSFT] says:

    > If anything, the direct cast should’ve been easier to write instead of the speculative cast via "as".

    I second (third?) that, though I’m not sure about which syntax I would actually prefer for that. Personally I’ve always liked ML/F# syntax of "(x : T).y", but that would conflict with operator?: so it is not an option. I also like functional cast syntax which Delphi uses (and where, I believe, C# got "as" from): "T(x).y", and, so far as I can see, it would not introduce any quiet changes to existing code, but that has the potential of being confused with instance creation – as many other languages, such as Python and F#, use it for that.

    I actually like VB operators for that, their names are really pretty clear. If you do an up/down/interface cast which you assert will succeed, you use DirectCast(). For the same where the cast may not succeed and you need to check, you use TryCast(). For conversions (where representation changes), you use CType(), where "C" stands for "change".

    > To rewrite this using as instead doesn’t look quite so tidy. Maybe you could put the as operation and assignment inside the IF condition and then check the value returned by the assignment operator, but that doesn’t look so nice.

    > With version 3.5 of C# and before, the only option I see is using the "is" and "as" operators with lots of "if" statements like others have discussed.  Does anyone know another way?

    From my observations, a "typeswitch" construct for C# is one of the more frequent feature suggestions on Connect. It would be nice to have that, as it’d also remove most of the need for is/as – if you can do a check and bind a result of that check to a scoped identifier all at once, that’s usually all that is actually needed. That said, it’s purely a convenience feature, and would probably be used less than, say, auto properties, so if Eric says that those have barely got in the language, I don’t have high hopes for typeswitch.

    > How do the casting operators behave when they encounter a null reference?

    The semantics are pretty much common sense. Any cast to a reference type or to a nullable value type will return "null" – which, by the way, means that even if (T)x didn’t throw, it doesn’t mean that (x is T)==true, so you still need that null check. Unboxing to a non-nullable value type will throw.

    > I’m curious why "(foo as Bar).Baz()" is considered an anti-pattern.  Is it just because of the potential for a null-reference exception?

    It’s because you’re essentially saying two contradictory things in a single expression. When you use "as", you say "maybe this isn’t really a Bar, so please don’t throw right there, but tell me instead. When you use operator. on the result, you say "this is never null", which implies "this is always a Bar".

    From a pragmatic point of view, if a cast failed, I want to get InvalidCastException, and not NullReferenceException. The latter can happen for numerous reasons, which would complicate the investigation somewhat. The former unambiguously identifiers the real problem.

    Of course, it’s a much bigger deal when people don’t use the result of "as" without a null-check immediately, but when they pass it to some method (which passes it to another method, which raises an event which stores it in a property …), and then somewhere down the line (and much later) some code tries to use that value as if it wasn’t null, and dies. That kind of thing can be notoriously hard to debug.

  22. Joren says:

    Making sure all non-private methods throw ArgumentNullException whenever null isn’t explicitly a sensible argument helps a lot in the null-propagation scenario as far as finding the problem goes. Of course it’s still a lot better to immediately throw an exception, and infinitely better to immediately throw an exception that actually specifically tells you what’s wrong.

  23. Gabe says:

    I’ve noticed that my WPF code is full of the dreaded is/as (anti-)pattern. For one thing, there are objects all over the place: ValueConverters, events, DataContexts, and more, all deal just with objects. I frequently need to know "do I have a List? how about a List of strings? a Dictionary? a plain IEnumerable?" or "is this a textbox? a checkbox? a listbox?" and I don’t see a cleaner way to avoid the is/as if-block.

  24. Pavel Minaev [MSFT] says:

    @Gabe, the block itself is not a problem in the scenario which you describe. The problem is a double check. You should use "as" followed by a null check in typeswitch scenarios, not "is" followed by cast or ‘as". If you use StyleCop, it will actually point that one out (and, IIRC, so will ReSharper).

  25. jordan says:

    Why can’t the compiler – or the JIT – optimize that case? For a local variable, it’s not like it will have changed between the is and the cast.

  26. TheCPUWizard says:

    Some great comments here…

    @Aaron, as far as a "better way" it largely depends if you have any control over the class hierarchy. If you can add a "Dispatch" method to each class in the hierarchy, then the "Double Dispatch" design pattern can be applied. This is very effective when two class hierarchies need to interact in a manner specific to the actual instance within each hierarchy (since C# – like many other languages evaluates parameters for a match based on declared and not actual type).

    If you do NOT have any control, then a potential alternative [IMHO it is subjective if it os "better" or not] is to build the dispatch using reflection

  27. Duarte Cunha Leão says:

    DRBlaise:

    Liked your note on the usage of the «dynamic» keyword for dynamic method dispatching.

    Many times I have missed this type of method dispatching: I first fell in love with the LISP programming language (CLOS, defgeneric, defmethod…).

    With the dynamic cast one explicitly states: "I wan’t dynamic method dispatching on this call; please choose the most specific method overload, at run-time, according to the specific type that appears in this variable".

    And with methods of more than one parameter, non-dynamic parameters can statically reduce the set of possible method overloads, while dynamically parameters finally choose one at run-time.

    Anyway, as tempting as it seems, and being a (somewhat) conscious programmer, I wonder whether the pattern should be used at all. How does it compare in speed to the normal already mentioned patterns? Would it be a sin to use it?

    If it is much slower, however, it does seem possible that the compiler could provide an optimization for such use (?).

    As long as it "looks" good, I’m almost sure a lot of people will be using it!

    Also, with this post, I realized that casts may do conversions, if needed, to achieve their goal (that of returning a value of (i.e. assignable to) the specified type, null, or throw).

  28. Gabe says:

    Pavel: As Aaron noted, it is really uglies-up the code to stick a bunch of local variables and nested ifs just avoid the is/as. Consider this code:

    var formvalues = from e in form.Children select (e is CheckBox) ? (e as CheckBox).IsChecked : (e is ListBox) ? (e as ListBox).SelectedItem : (e is TextBox) ? (e as TextBox).Text : null;

    I don’t think there’s any way to do that without using is/as that’s anywhere near as tidy. If there is, I’m certainly open to it.

  29. Mark says:

    Gabe: What’s wrong with polymorphism?  Extend each class to implement an interface that provides GetFormValue().

  30. Pavel Minaev [MSFT] says:

    @Gabe, if you want neat over fast, you can always write a typeswitch yourself using lambdas and method chaining. It’s trivially done (searching on MSDN blogs should find you some implementations), and it looks much neater, but it’s somewhat slow because of delegate virtual calls overhead.

  31. Gabe says:

    Mark: Polymorphism is fine, but I didn’t create the class hierarchy. Even if I subclass everything that I might need a value from, I can’t get the rest of the world to use my subclasses; a DataGrid will always use a TextBox and there’s no way to tell it to use my subclass; I have to interoperate with code that is already written, libraries I don’t maintain. I’m sure you get the idea. Extension methods would be nice, but that only works if you know the types at compile-time.

    Pavel, compare these two options:

    var formvalues = from e in form.Children select (e is CheckBox) ? (e as CheckBox).IsChecked : (e is ListBox) ? (e as ListBox).SelectedItem : (e is TextBox) ? (e as TextBox).Text : null;

    vs.

    var formvalues = from e in form.Children select new Select<object>(e).Case<CheckBox>(x => x.IsChecked).Case<ListBox>(x => x.SelectedItem).Case<TextBox>(x => x.Text).Default(null);

    Which one better expresses the intent of the code? Which one is easier to read? Which is easier to understand? I think the first one wins on all counts. In particular, the Select class is something I would have to write, which means it’s 100+ lines of generic metaprogramming code that has to be maintained by my organization. Since the Select<>() idiom is not standard, you really have to study it to figure out what it does.

    And the whole reason we don’t like the first option is the slight perf hit of having the redundant "is", so it doesn’t make sense to replace the extra "is" with a method call, a delegate call, and all the other logic inside the Case functions. Not to mention that the first option stops executing the logic when it finds a matching type, while the second option still has to make a function call for each Case regardless of whether it does anything, plus it has the overhead of constructing a new Select instance for every child of the form.

  32. Aaron G says:

    I’m probably a little late to be posting another reply here, but I might as well try to clarify something.

    I’ve come across a number of instances where double dispatch would be inappropriate, inadvisable, or just plain impossible.  For example:

    – Database entities.  Unless you can show me an entity framework that does a competent job of handling multi-table hierarchies and supports OO concepts like abstract base classes and double dispatch, the result is often a mess of conditionals to account for the impedance mismatch between domain class hierarchies and discrete entities.  I love Linq to SQL, but it’s not up to that particular task, and neither has any other ORM that I’ve tried.

    – UI functions.  In any medium-to-large scale app you are very likely to have some kind of middle tier that contains "business logic" but is UI independent (some consumers may not even *have* a UI).  Without some crazy code-injection technique like AOP or virtual extension methods, it’s somewhere between impractical and impossible to make the class capable of instantiating its own editor.  Let’s say you’re representing several types of these (related) objects in a tree or list view and the user has initiated an edit – how do you know what editor to bring up?  Again, I think you’re pretty much stuck with the mess of conditionals; you might have access to a discriminator and be able to use a switch statement, but that’s only making the code nicer, not solving the design problem we’ve described.

    – UI control hierarchies.  It’s a *very* frequent occurrence that some particular Winforms control re-implements some non-virtual property as "new", and if you fall into the trap of always accessing it through the base class then you’re in big trouble.  I don’t know about anyone else, but in my experience, the "Text" property is notorious for behaving strangely.  This may be poor design, but it’s also someone else’s design, there’s nothing I can do about it.

    – Messaging.  You’re communicating with some hardware device that may have sent you any of a dozen or maybe a hundred different messages, none of which have anything important in common (except for being "messages").  You have to respond to the message, but first, you obviously have to figure out what it is.  Similar to above, if you have control over the message class hierarchy, you can add a discriminator so your handling code can be a nicer switch statement, but it still suffers from the same problems described in the earlier reply (the contract says that it can handle any message, even though maybe it can’t, and the author may indeed have no idea at all what "HandleMessage" means for any given message).

    Maybe I just haven’t been out there long enough to know the "right" solutions for these, but in my limited experience, the only truly elegant solution is dynamic programming, and I assume that’s why the C# team is working on it for C# 4.  (And in a sense, dynamic typing doesn’t really make the design problem go away, it just provides a more convenient way of expressing the workaround).

    I also like the typeswitch that Pavel mentions but, of course, that is just syntactic sugar, it’s not any more efficient or safe than the is/as ladder and doesn’t make the underlying design any better.

  33. TheCPUWizard says:

    @Aaron G (and any other interested reader). If you have been folowing the information available for 4.0, the primary (but not sole) reason given for dynamic is for interop with other languages, and NOT for functionallity directly contained in C# or other strongly typed languages.

    In my professional opinion, considering AOP, code injection or IL rewriting as "some crazy technique" is at best short sighted. Consider that something as fundamental as code contracts is impleented in exactly this fashon.

    I have successfully used "synthesized double dispatch" (ie multiple calls occur, but NO conditional branching) in all 4 of the categories you mention. This is NOT to say that such an approach is always a good choice, but it is one that can be considered.

    I can be contacted as david "dot" corbin "at" dynconcepts "dot" com by anyone interested in these approaches.

  34. Szindbad says:

    Hello Eric,

    Do you see Gabe’s code fragments? Do yo see what kind of monster are you creating?

    "var formvalues = from e in form.Children select new Select<object>(e).Case<CheckBox>(x => x.IsChecked).Case<ListBox>(x => x.SelectedItem).Case<TextBox>(x => x.Text).Default(null);"

    Ouch. How this will interfere with dynamic?

  35. Chaitanya S says:

    I'm new to C# and have been reading your blogs. They are very nice and informative. Thanks for them.

    I may be wrong but please clear my doubt.

    I have a question here:

    You have written in this blog:

    ["….The "as" operator will not make the representation-changing conversions from short to nullable int like the cast operator would….The "as" operator only considers reference, boxing and unboxing conversions."]

    This means that boxing and unboxing are not representation-changing conversions and so "as" handles them.

    Now, in another blog blogs.msdn.com/…/representation-and-identity.aspx you have mentioned that

    ["…. Boxing and unboxing conversions are all representation-changing conversions…".]

    I find the two statements (in brackets above) from two different blogs contradicting each other. Kindly explain which one is correct?.. Please correct me if I've misunderstood them.

  36. jmcf125@hotmail.com says:

    It's all pretty good, but you seem inclined to use as instead of a cast, so this isn't completly unbiased.

    The better option (at least for me) would be to use a method (if you use a try-catch or try-finally block, that surely won't fail).