Opinions on C# dynamic

Started by
14 comments, last by Ravyne 12 years, 8 months ago
My primary project ( non gaming related ) is written in C#, but until recently for various reasons I have been stuck on the .NET 2.0 runtime, so 3.5 and lower features were all that was available to me. Recently I had the opportunity to upgrade everything to .net 4.0 so I have started looking at the new language options in ernest for the first time. I am currently working with a Facebook library which makes heavy use of dynamic for doing, um, dynamic bindings to JSON code.



Initially it seemed remarkably powerful, almost like magic. It solved so many annoying problems and boilerplate code, and would be an absolute godsend for interfacing with COM interfaces, like those provided by Office.



That said, after using it for a while it just started feeling... wrong. Like the language was taking a step back for the sake of conveinence. Plus I noticed an actual drop in productivity, at least initially. The complete loss of intellisense was more than a little bit frustrating, but worse of all, it shifted all the problems from the compiler to run time. So, if I called a method that was named wrongly ( from the JSON results ), it would compile just fine and then blow up at runtime. If C# was already a duck typed language, it would make a lot of sense, but for a strongly typed language, this just seemed like a very bad development.


Again, this is all just initial impressions, but part of me just feels like the addition of dynamic, although staggeringly powerful at times, was a very bad language feature for the language as a whole. Couple dynamic, with "var" and anonymous types and I can forsee some incredibly terrible code in the near future. Dynamic just seems like one of those features that is going to cause more problems than it ever solved.



I am curious what other people think. Do you like the addition of dynamic? Do you use it? Do you forsee it leading to a great deal of bad code in the future? Am I just being a grumpy old man yelling at people to get off his lawn?
Advertisement
I have never liked dynamic typing.

I can see why some people do like it, and I sort of understand their arguments, but I still strongly disagree that any form of dynamic typing is a good thing in the long term.


That about sums up my view on it :-)

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

You pretty much nailed my opinion on the matter:
- It pushes error checking responsibility to run-time instead of compiler catch-early
- It reduces intellisense
- It is difficult to get comfortable with when otherwise working in a strongly-typed language

I suppose as long as it is only used for its intended purpose, it is a nice feature - I don't know why anyone would go out of their way to try and use dynamic typing in C# unless they had to. Perhaps someone coming straight from Python?

As for general abuse - I don't necessarily believe that a language should sacrifice potential gains in order to protect a programmer from himself. I suppose I could see this opinion differing for someone who primarily works with a team, or has to debug others' code, etc. For a mostly loner hobbyist like myself - well, as the cliche goes, I mostly eat my own dogfood..

p.s. As a closing statement, I was originally going to compare the potential abuse level of C# with other languages to try and make a half-ass point, but I don't want to be "that guy who started the language war on post #3" so I deleted it :cool:
I agree with what has been said about dynamic. It has uses however few they are.

However, your stance on var and anonymous types aren't really valid. The var keyword is checked at intellisense time (yes I made that up). The type must be discernable by the compiler, and therefore be able to show you what type it is in intellisense, or it is an error. It's basically a productivty shortcut and has no runtime presence whatsoever. Anonymous Types and Delegates etc are pretty much the same thing, though I don't use anonymouse types at all, and life would be painful without anonymous delegates, which are 100% checkable at compile time.
I have used it once so far in a little VM. I used it for Mathematical operations.




public object Add(dynamic lhs, dynamic rhs)
{
return lhs + rhs;
}


That was a lot faster to code that then having all the overloads for all the existing types. Of course, this might not perform in tight loops. The .NET runtime does perform polymorphic caching, but I never bother to do any benchmark it because the VM was fast enough for its purpose.

I agree with what has been said about dynamic. It has uses however few they are.

However, your stance on var and anonymous types aren't really valid. The var keyword is checked at intellisense time (yes I made that up). The type must be discernable by the compiler, and therefore be able to show you what type it is in intellisense, or it is an error. It's basically a productivty shortcut and has no runtime presence whatsoever. Anonymous Types and Delegates etc are pretty much the same thing, though I don't use anonymouse types at all, and life would be painful without anonymous delegates, which are 100% checkable at compile time.



I don't have anything against var or annonymous types by any means, I realize both are really valuable language editions and are still both strongly typed. However, coupled with dynamic, they will allow new developers to learn C# is a typeless manner, which is rather scary. For example, when LINQ first came out, people quickly ran into a hurdle that you can't simple return anonymous types from a function call, so generally results from a LINQ qeury were converted to List<Something> or similar. Now, a programmer can simply say "oh screw it" and just make the return type dynamic, never have to really understand what exactly their query generated. People writing code they don't understand is almost always a bad thing.

I have used it once so far in a little VM. I used it for Mathematical operations.




public object Add(dynamic lhs, dynamic rhs)
{
return lhs + rhs;
}


That was a lot faster to code that then having all the overloads for all the existing types. Of course, this might not perform in tight loops. The .NET runtime does perform polymorphic caching, but I never bother to do any benchmark it because the VM was fast enough for its purpose.





See, this is a good example of where dynamic is awesome and horrible. Its awesome because of the convenience it provided, horrible because I can get away with:



var total = Add( pontiacGTO, goldfish);



And the compiler will wistfully allow my stupidity until runtime then BOOM.

I am curious what other people think. Do you like the addition of dynamic?


I didn't, though I understood some of the reasoning. I think that as far as implementations go, it's pretty solid compared to what it could've been. Currently I kinda like it. I like having the tool in the box, even if it's a relatively dangerous tool. The places it works best are already more dangerous in similar sort of runtime error ways, so I'm okay with that.


Do you use it?
[/quote]

I use it for some things. Most often I use it to allow dynamic dispatch on methods; this is (imo) its best use in C#. I also tend to use it in WCF services to stabilize the interface, and storage for parameters in a command pattern.


Do you forsee it leading to a great deal of bad code in the future? Am I just being a grumpy old man yelling at people to get off his lawn?
[/quote]

I've worked on .NET 4 projects for a bit over a year now, and maybe it's the quality of the teams or the lack of use due to unfamiliarity but I've not seen much bad code from it. Most times it's being used in WCF where you've got tons of runtime issues anyways due to configs/network issues/serialization oopsies, or to replace the use of 'object' and ugly unwieldy casts.

And the compiler will wistfully allow my stupidity until runtime then BOOM.



I never found that to be a problem in practice. If it is used with object created by programmers while writing code, unit/integration tests will usually catch the mistake.

It only gets problematic if the object type is selected from values from an external source, like say an external file or your JSON example. Then extra validation has to be done before calling the function, but since the type is selected externally, it has to be validated anyway before being used.

However, if you do have a large project with a lot of programmers, I certainly would recommend to stick with static typing and only allow a few leads to use dynamic if it would significantly improve the code. My example fits that because the VM I wrote does not deal with types directly, so a switch statement with a type check would have needed to be done for each math operations if I did not use dynamic.



result = VMMath.ADD(src1, src2);


instead of say

if ( src1 is int )
{
result = VMMath.ADDInt(src1,src2)
}

else if ( src1 is float )
{
result = VMMath.ADDFloat(src1,src2)
}

else if ( src1 is string)
{
result = VMMath.ADDString(src1,src2)
}
.....


A different design can work around that problem and not require dynamic and still be a one liner, but it's all that was required for the VM I built.
Using var is ingenious for LINQ. Whether you're using LINQ to SQL or LINQ to objects it removes a lot of guess work in which type you need to cast to/from. I've never had an issue either supporting or writing new code where var messed me up with LINQ. Granted, that's about the only places I've seen it used heavily but it's treated me pretty swell.

This topic is closed to new replies.

Advertisement