We use dynamics similarly to your example. A large, ever-evolving JSON object that needs converted into a legacy XML format. Parse the JSON into a dynamic, add the legacy data we need that the JSON does not contain out-of-the-box, serialize that into an XML object and then run an XSL transform against it to get our final XML. Performance is not really a concern, so the dynamics made it quite easy to do. Beyond that, I'm totally with you.... I don't recommend using them. As always, great video! The Python thing, while disturbing, was pretty cool. I didn't know that was possible.
The lack of IntelliSense is the main reason why I do encourage people to use TypeScript in almost all JavaScript commercial projects (even for non-commercial little projects it's good choice tho). I just cannot see (even small but) scalable app, without IntelliSense and error checking in IDE/Compiler/BeforeRuntime. It's definitely the one of the possible reasons to project's failure
The JSON case was the exact reason I ended up using dynamic, and it has been on my mind whether to move away from using it, as it is used in a production service. This completely answers my question! Thank you!
Thank you for this breakdown on dynamic. I like your videos, your practical approach really helps to understand these features. Would you consider doing the same on ref and out keywords (parameters)?
It is probably worth writing a DTO with just the fields you want to read. Maybe it takes a tiny bit more time than a dynamic type, but you don't have to wonder every time you access the object what are the available fields.
In my whole career as a C# developer & PM, I just had one project, with one usecase which justifies the usage of dynamic. I told my Staff, that, when they think, dynamic is necessary, they do it probably wrong and it's more likely, that they have a glitch in their design.
@@lizard450 As part of a product database, I recognized the need to map the properties of the articles not in static tables (SQL) and corresponding C# objects, but to give the user the possibility to create parameter sets. These sets are defined once with their properties and structure and can then be used for other articles of the same type. However, it was necessary to use specific data types incl. type-related validation for the respective attributes. Since the attributes essentially all have the same structure, I did not want to implement specifically against the data types. So no Attribute_Int, Attribute_String etc. That would have meant type checks and/or casts in too many places for me. I preferred to have cleaner code, I gladly accepted the performance penalty. Therefore there is an interface "IAttribute" with the dynamic property "Value". I know it sounds strange but when you see the project and the high degree of dynamics and flexibility you'd understand ;)
@@TuxCommander thank you very much for your reply. It does sound strange but I do appreciate the effort. I think in your situation there I'd have used json and the value would just be a string. Who knows maybe even TSON
@@lizard450 plesure ;) Yeah, I know, sounds odd and is hard to explain but json or storing the values as string was not an option due to binding in WPF and dynamicly generated UI elements as well as calculations/comparisons which needs to be perfomed on the attributes and not to mention the export features. This would have caused to many explicit casts and validations. Actually the dynamic type helped here a lot in having a clean code. Even I was not happy with it in the first place from from the performance perpespective but also this is managable and goes under in the rest of the app actions. The App is in total quite fast and responsive that you would not expect its that structured under the hood.
@@igorthelight I don't know, in a lot C++ those unknown features tend to only work for the specified purposes, (though I suppose you could say easily misused, but not really fair when everything in C++ can be so grossly misused, not just hidden features) whereas dynamic addresses a problem that's better solved without it. (the only real reason to have it in the language anymore is for backwards compatibility)
@@Spartan322 Agree. But "dymanic" is useful for a few things like MS Office integration and maybe some other stuff. But I agree that we should use it as rare as possible. It's slow and errors are harder to debug.
I mean with JSON u can deserialise to a JsonObject and then do .GetValue and it would probably be faster. But dynamic does have a use case for the once in a million situation and should not be undermined
I am watching your videos for a while already to improve my coding skills and/or get to know about new features or oppinion on coding styles/habits. This video was quite special for me though. The moment you typed your github account URL I was like "Wait a sec, is that the Elfocrash for real"? And yea, you are. I am big fan of Lineage 2 Java server emulators for like 10 years already and I have seen some of your work as well. Kind of nice discovery. World is really small.
dynamic was added for a couple of reasons: 1.) VB - (not VB.NET) is all dynamically type. The var keyword was also borrowed from VB (to make C# look more friendly to VB developers - but var in VB and var in C# are totally different). MS wanted to encourage more developers to move from VB to .NET. Same reason for having ViewBag. In the old ASP this was used, so some people thought is should be there in ASP.NET as well (ViewData is a little more structure alternative) 2.) Office / COM interop is actually somewhat easier with dynamic. 3.) JavaScript / Python are dynamic languages. As JavaScript got more and more attractive for developers, MS wanted to add "stuff" to .NET to make it easier for JS / Python developers to migrate to .NET. It was always a problem for MS to establish new technologies. The old stuff worked usually quite well and developers would not migrate. So new developers would gravitate less and less to the MS platforms. The challenge is: developers are just as emotional as other humans are. If data scientist hear that Python is the go-to language now used by everybody - they use it. Even though Python is terribly slow, has some odd syntax (not as bad as Perl), dynamically typed (which is B.A.D. by design) and is just as hard to learn as C# or Java. You can see these things in many areas. Why does hardly anybody use the preprocessor in C# code (besides #ifdev DEBUG) - well the C# community doesn't do it. But in C++ everybody uses the pre-processor. You are no real C++ developer if you don't use the pre-processor (you have to for #include). Another example is the syntax of PowerShell. Kind of similar to Perl. You guess why... These things keep repeating and are usually driven by business decisions.
I have used it for a dynamic api for automated tests to great effect. Not many use cases but when one comes along it's super well implemented and an intuitive language feature.
So dynamic method calls have something I think is called Double Dispatch, which is useful for a visitor class without having to write accept methods on all of your objects. So say you have a heterogeneous list of objects, and you want to call different visit methods based on their runtime type. If you just call visit on the object, it gets statically bound to the overload that takes object. But if you first cast the objects to dynamic (and/or the visitor I think), then it will call the most specific overload possible based on the runtime type. Then the pattern becomes just add another .Visit overload for each new type you want to handle, no other boilerplate code required. It even works to subclass the visitor.
I have a helper class in my code where I use this specific mechanism to return true or false depending on whether a variable is a generic IList or not :-)
Nick, I think your recollection of why dynamic was introduced is a slight bit off. The keyword was a side effect of Microsoft's work on the DLR - Dynamic Language Runtime, not the end goal. DLR was an effort to enable dynamic languages (Python, PHP, Perl, etc...) to target the .NET. Once DLR was made available, C# was able to take advantage of it by introducing the dynamic keyword. Keep up excellent work.
This is correct. IronPython and IronRuby are implementations of other languages which can compile down to MSIL to interop with other .Net languages in the same way that you can access VB.Net or F# from C#. It shouldn't be thought about like the introduction of Records as a part of the language, instead it is more like the introduction of var to make LINQ work. Unlike var, dynamic isn't as valuable for wider application, but for the specific use cases it supports it can be invaluable.
Viewbags were also my first exposure to dynamics. I went out of my way to convert everything to using the explicit model objects, but I think MVC 5 was a requirement for that.... it was at least 6 years ago now.
I agree with you about NEVER using dynamic - right up to the point I found a project where dynamic made complete sense because of the coding simplicity that resulted. I now ONLY use it ALLWAYS in conjunction with new C# functionality such as "if(x is type y){dosomething(y)}" and "var allvariables=dynamiclist.Where(q=> q is is Variable vv);" and so so on. BTW The project is a general parser for translations between different computer languages. The source code as a string list was converted to list of records of type Variable, Keyword, Operators etc. - the complete tokenised source code all now stored in a single dynamic list rather than a string list.
I am using dynamic to get dynamic result from database -> odata api -> power BI. Works great, since i cannot define static model for some queries, otherwise the powerBI would be painfully slow.
For Json APIs, you can also use Edit->Paste Special->Paste JSON as a Classes, at least in Visual Studio (I assume Ryder has the same feature). That creates the necessary classes for you automatically.
Sure but the thing is that when I'm prototyping I don't care enough to build POCOs and do serialization. Just wanna integrate with the thing. There are actual proper JSON API libraries that provide the appropriate wrappers around the core contracts and take care of all the linking, pagination etc so in that case I would use that instead.
Using this to work with dynamic Office objects was nice, and a runtime hell at the same time. Using it for IronPython is a valid use case, since many mathematicians will build their data analysis with Python und NumPy, and then hand off their big data or data analysis project written in Python to you for "integration".
One use case where I‘ve encountered dynamic, is to have runtime polymorphism for method overloads. Method overloading normally leads to early binding, but when you cast an object to dynamic before passing it as a parameter into a method, the decision which method to call will be made at runtime, based on the object type.
@@hck1bloodday That depends on the use case. First problem is, you cannot do method overloading based on generic type constraints, try it. You can only define one generic method and then overload it with specific types. Even then, the problem with the approach will be that the method binding will still happen at compile time, meaning that concrete types can be hidden behind more general types and a method with the more general type will be picked by the compiler. Sometimes you need the polymorphism at runtime.
@@leonardkupper7250 I will try that, may be using a genérico with interfaces instead of concrete types could solve that, I'll be back here with the results 👍
Another scenario where you might have to use dynamics is when using reflection. If you need reflection, use object wherever you can, but sometimes the code you're trying to invoke just won't accept the object type and you'll have to pass your object, which is already the required type and simply cast to type object by reflection, must be passed by casting to dynamic. If you still want to double check what you're working with you can use the methods reflection offers to double check.
Nice one Nick, keep them coming :). I agree the use case for dynamic is limited. We use Jint (Javascript interpreter) on one of our projects and this is one of those use cases as you are traversing across language types and who am I to question a wizard like Sebastien Ros.
Dynamic/scripting languages are very powerful and most often they offer intellisense also. C# DLR is written on CLR that's why it is slow. At runtime, the dynamic code is translated into DLR and then compiled and executed and that is a performance killer. C# intellisense is also written for CLR but they could have made it available for DLR but they did not. In the old days, foxpro was a dynamic language with speed comparable to C language. It was very easy to design application frameworks and ERP software in it. But it took them ages to introduce dynamic keyword in c#, prior to that they wrote tons of code to create dataset code in order to handle a variable number of data fields.
Nick, would you consider having a shortcut key indicator superimposed in the corner of your screen, occasionally I see you using a specific shortcut combo that I didnt know existed, would be handy to simply re-watch the video and see the actual keys pressed.... Just an idea anyway, I've seen other coders do this as well.
I think Rider has a plug-in for such presentation. I just have to find a way to make it not invasive because it can get annoying for me when I’m making the video
@@nickchapsas ah, I thought it was recorded in the background and then superimpose on top of the video after.... if not, then yeah, that'd be annoying.
I agree with you, but the dynamic type saved me one time adding a new app that later turned into a feature in an app at work. Short summary, business changed the requirements multiple times while we were implementing. We ran into so many issues on the server code, but I decided to use dynamic to speed up some of the changes. I added the appropriate unit tests and integrations to be sure it wouldn't break. It's touchy because if someone adds something new and doesn't add new tests it could break, but it saved us a lot of time. A refactored would've really delayed us even more back in the timeline that the business had already caused.
That was also the time when Microsoft had quietly decided that .Net was the past and Visual C++/Javascript was the future because web. I went to Build around then and ALL the sessions were around "how to move from .Net to C++/JS and switching to WinRT (UWP) which was going to replace .Net with a new architecture based on C++ and JS. JS is an inherently dynamic language (one reason I loathe it so much). This was when Win 8 was coming out at well and I remember at the time that a lot of us noticed that the announcement of UWP didn't mention .Net at all - and the response from Microsoft was bizarre - that we'd learn more close to the release date. In fact, it seems that Microsoft threw together a bridge between .Net and WinRT because a lot of stuff in WinRT was missing or cripples in .Net at first. The other bridge was to add "dynamic" so interop with WinRT JavaScript could work. In the end, WinRT and UWP tanked big time and the idea of writing apps for Windows in JS just never happened. But we're still stuck with "dynamic" which fortunately, most C# programmers never use.
Good one Nick. Minimum size for an object(ref type) on a 32-bit machine is 12 bytes (8 bytes overhead+4 byes to store info). Class MyTest { public dynamic field=(int) 100 ;} even in this case it won't consume 12 bytes (including 4 bytes int field) for an int value instead the 'field' will be treated as an object because of dynamic and thus the size will be : 12 bytes (MyTest class) + 12 bytes (for the dynamic field) = 24 bytes. So in a performance / resource intensive system it's a complete no-no.
I use dynamic for COM interop because the COM objects have vital fields and methods I need to use, which aren't showing in the static types. The only other way to do that would've been heavy use of reflection. Wouldn't be more stable, cleaner or faster...
I use ExpandoObject to dynamically add properties from a source object, i.e. to support the "fields" query parameter for a REST API. So you can do "?fields=id,name" and the API will only return the id and name fields of the requested resource.
You can also parse response from last example without using dynamic and without creating extra classes, you can use something like: var jObj = JObject.Parse(response); var followers = (int)jObj["followers"];
What's people's fear of creating a data class? Strongly typed variables alone makes it worth it. And if you're using C# 9 you can create a record to make it even easier. Edit - Regarding the end of the video, you can create a partial contract to get just the data you need.
I was working with serializing and deserializing the other day, and this would have been a really easy way to get the object parsed and passed between functions, of course, I'm not mad that I found another way around the issue. But what I really needed was to find a way to **Cast** an unknown variable to a type variable, and the compiler wasn't having it. So I had a variable of the type "Type", and the compiler told me that I was using a variable like a type, but that is because it is literally a **Type** variable.
Couldn't agree with you more about all your points here. I, too, was always thinking to myself "I'm not gonna use this ViewBag, why would I when I can use the ViewModel?". Also, when I see "dynamic" in someones code, I immediately think... okay, who was being lazy here? lol
Hey Nick, can you make video on DI with singleton? Do we need to check for thread safety while using singleton or its taken care by default by AddSingleton ?
Is there any alternative to dynamics in situations similar to: private static T GetSum(T x, T y) where T: struct, IComparable { return (dynamic)x + y; } I have situation which is more complicated than this, but main problem is that I want to use arithmetic operators in generics where I know that generic type have those operators.
@@deidian635 My use case is bit more complicated then this example. Making different methods for each datatype would lead to significant duplication of the code, where just small part is related to dynamics. And I would need to write at least 3 versions (long, double and decimal). It would be really nice having some way to constrain types of generic to ones with arithmetic operations.
@@deidian635 Compile can easily optimize those calls. Every time + operator is called it can replaced with appropriate add assembler instruction if final compiled version of the code for every primitive type. It would be almost zero performance hit. My whole point is that there should be a way to constrain generics to arithmetic types. C++ constraint is compile time checked, after that it is using normal arithmetic operators as they would be normally used. There can be even a keyword which can say that type is arithmetic (as we can constrain it to class or struct).
Hey Nick, Am very glad to see the real use of dynamic. Even one of my project I really used it for the same purpose. But in my case is little different . I read the database result which is multiple resultset, and the number of resultset is varies depending up on resource. And the result set order also vary depends on the what data is available. so I can not use the POCO to bind the data. This is where I used dynamic with some logic in the resultset columns. Do you suggest any other alternative I can try?
Office interop with dynamic is a helpful last resort but usually only truly needed if your users are operating across very different versions of office PIAs versus the ones compiled with the project. If that's the scenario though, dynamic often ends up kicking a problem down the road rather than fixing it.
Dynamic can come in handy when doing things like metaprogramming but other than that I struggle to find a usecase. Even for things like prototyping I tend to just build limited pocos or generics
Only use i had was to transform a few props in 100 000 json objects stored in a DB. Json objects where made by 3rd party so i did not care or know the full schema of the objects, just for the props i needed to fix.
For the same reasony why I wouldn't use JObject or any other wrapper around the json object. During prototyping I want to get to the finish line as quickly as possible. If that Having to deal with parsing and root elements and try get values is not something I wanna have to do. Simply traverse the json object as if it was part of the code.
Thank you Nick! Great content, never heard about IronPython before. I see it's still a maintained project, so there must be some use cases for it. Just wondering how this compares to C# scripting...
One decent use-case for dynamic is the ability to use JSON objects without writing class definitions for these objects. It's not a GREAT idea to use in large scale enterprise applications, but it's great for small one-off console applications. This also can handle changes to the underlying json object as long as the elements you are accessing weren't changed.
Sitefinity CMS makes heavy use of dynamic. Admins can define new types in the CMS admin panel and component cshtml templates get an object with a dynamic property called "Fields" to access any custom properties. The whole thing is very interesting
14:13 "Why I don't use them, and why they don't have a place in my code." ...except for an obvious use case that mirrors what so many are doing when it comes to consuming API.
I think union types is another use case as to why you'd want to use dynamic. I'm not super happy that I do but basically it either use dynamic or use recursion which I think kills performance as much as dynamic does.
Dynamic in that case is actually a JObject which gives direct access to the json properties. Explicitly specifying it would be faster in code but slower for rapid prototyping. When I’m creating a prototype I don’t care about performance
@@nickchapsas ummmm, ok, that's something I am gonna have to take a look later. Thanks for the info. Likewise I usually use JObjects because I don't really like to loop thought a dynamic object
There are times it actually can work faster. I ended up using when I had no idea of what data type I was going to have. Then I passed the dynamic type to an ODBC parm.
personally using dynamic to have UI (de-)serialization That way, no strict rules have to be followed when serializing those to json it is quite handy for very, very specific usecases
Nice explanation. I am using elastic to search across multiple indices to return different schema types. I am using dynamic return types over . Would love to know your thoughts?
Ultimately it is because of contract safety and performance. Contract safety in this case is the least of your concerns so in my case it would be performance.
It just feels like syntactic sugar for accessing a nested HashTable without checking for key presence. For the python example, returning a Dictionary at least would allow you to easily enumerate it.
The good use of dynamic or just a simple implementation as ExpandoObject is for rest api calls like you showed. BUT... Not when you have an obvious response which you can easily create a poco for but when you have really DYNAMIC data/response and you need to hold the values. For instance I can get the same data from a sensor but different sensors might have different json models. So I can't specify a poco. I need dynamic dictionary like ExpandoObject provides and create models on the run. Especially good when the infrastructure comes from a client and is existing one. I agree that this might not be the fastest but just parsing small chunks of sensor data is not really that demanding operation. Also it allows to work with nested levels within json which is the usual case. One level json is the best shape but we rarely see those in real commercial apps, don't we? One more good thing about ExpandoObject is that you can write extension methods for it which you can't for 'regular' dynamic type. It is definitely useful but not exactly for writing calculator or calling external api for response you know model of up-front.
IL is such a hard topic to talk about because it is so disconnected for regular C#. I am planning to talk about it a bit more on a video about Lowering but I don't think I will ever be making a dedicated video on IL.
I use dynamic to pass parameters to stored procedures with generic methods wrapping dapper. var parameters = new {Fullname = "Ibrahim Hussain", Gender = "Male"}; And pass that as dynamic parameter to the db call method.
@@nickchapsas yeah. I can pass the anonymous abject to a method parameter that accepts dynamic. Prevents me from having to use a different model each time I need different parameters
@@ibrahimhussain3248 Yeah so that's fine because the method has it as part of it's API as dynamic. You didn't use dynamic yourself, but rather Dapper accepts it. That's totally fine.
Using JObject directly would be the "correct" way to do ti but it doesn't provide the same developer experience. I just wanna traverse the path of the object in C# without having to deal with GetValue() methods and .ToString calls. The whole point of using dynamic in json is to skip over all that noise. Side note, dynamic in that context is of type JObject. It just gives you access to the json fields without having to go through the methods.
@@nickchapsas I'm not sure about C#, but in Java with Jackson library, there's a way to just throw away all unknown properties not defined in the object, so in your case, you could have a class that defines only followers property. Simple googling tells me about the MissingMemberHandling setting in Newtonsoft.Json. Not sure if that's performant or not, but this way, you get compiler checks and IntelliSense, which to some degree worth it?
@@Brawaru Newtonsoft by default will do that as well but if you have nested objects you still need to provide the class structure which is tedious. You cna technically "reroute" a property but that's too much work for a prototype.
Dynamic has its place, and can be crazy useful. The main value comes when a consuming layer needs to add unforeseeable information or behavior to a fundamental class. Without dynamic, your only options are inheritance or interfaces to try to extend the core class. These methods aren’t always the best route, as the base class might not be aware of the extensions to be able to gain value from them, but a dynamic base class CAN understand that dynamic extensions are expected to exist, and can act on them. This works very well for sharing data models across layers where, for instance, the UI is determining additional property values to store on a record. If you use a no-sql store, then it’s easy to store and retrieve these values by a base framework without ever needing to extend the framework. Just one example. Also, if you’re building a WPF app, dynamic properties are also bindable in XAML, which is really handy - and this can include Command properties. So instead of building new class systems for View Models to extend your data models, you can simply “aspect” behaviors onto the data models, depending on the view, to get the behavior the view needs. And you can do this in a structured way, so while the end result is a dynamic type consumed by the view layer, you still have structured, testable code.
Wrong title or did you change your opinion?. You said that you don’t use it in the beginning and in the end you said that you use it. Be consistent. That said is good that you mentioned when to use it and when not.
Well using it in non-production code explicitly for rapid prototyping, so it's only in code that will never see the light of day. When I say "never" i am only referring to code that other people are meant to see. When you're writting code that only you will see then you can do whatever you want, really.
Hah, I couldn't help but laugh at "I won't explain what COM is," because that would easily have taken the remainder of at least this video... Also though, it's arguably IUnknown too. :)
I have to deal with dynamic and viewbags nearly on a daily basis...and I can fuckin confirm it is a pain in the ass. Never understood why one would use this and still don't xD
You really did IronPython dirty. I wrote a whole automation suite that was scriptable with it. I didn't have to use dynamic at all, because a static class with Func properties defined all the extension points and the parsed script was expected to have top level functions of the same name. Anything that didn't match were just left null and not invoked. So the C# code was treated as the protocol for the Python script, while your Weird example does it the other way around which is definitely untenable. I wonder if this difference is why I don't share your disdain for IronPython. (btw these days there is also JInt that does modern Javascript, it's used in AngleSharp and Orchard among other things. So it's not a dead use-case as you suggested.)
Dynamic has its uses, specially when processing numeric data. Assume you want to perform a numeric operation on a list like standard deviation or mean squared error. Yes , you could check the type and have a different code set for each type ( float, double, decimal , int , unsigned int).... or you could use dynamic. A lot cleaner and concise. An even more complicated case would be if a formula could receive a combination of double , decimal and integers. Not a common case but it can happen , for example if you are working with a database and are doing a reporting tool. Dynamic is the perfect tool for runtime evaluation along with c# script.
Most of your other videos are very good. But here, you entirely missed the point behind dynamic / DLR. Dynamic was not introduced in C# to solve a problem in C#. It was introduced in .Net (not C#), primarily to allow scripting languages to run inside a .Net process and access the .Net/C# stuff running in this process. In other words, to allow running Python/Ruby/Etc. scripting code in .Net. Many scripting language are not typed and the compiler safety you are talking about has never really be a problem in those languages. You are mostly talking about the dynamic construct in C#. This is no more than synthetic sugar around the DLR, basically a side effect, which happen to elegantly solve few edge cases in C#, one of them being the COM interops. I would not use dynamic to call C# code from C#. That's not the purpose of dynamic. Dynamic is there to allow C# code to call objects, who's members are unknown at compile time, e.g. scripting objects or objects based on data. In this case, the runtime will actually ask the object for "what to do" (which the C# objects in your example have no clue about those dynamic methods), and then the dynamic runtime will fallback and use reflection on the C# object to invoke the method. This use case makes no sense. The expando object in your example is an exception in your example. Finally, about performance. Dynamic will be slower than static! And the examples in the video will be extra slow, as they are not real dynamic objects, but objects where the runtime emulates the dynamic behavior. A real dynamic object will emit just-in-time generated code to "glue" the dynamic call to the real implementation of the method logic. Depending on the quality of the object, the speed of this code will vary. Good quality code will be 2-3 slower than a normal C# call. But keep in mind, this overhead only happens when you transition from an object implemented in C# to an object implemented in Python or Ruby (or vice versa). The benchmark you provide are not representative for the intended use case of dynamic.
We use dynamics similarly to your example. A large, ever-evolving JSON object that needs converted into a legacy XML format. Parse the JSON into a dynamic, add the legacy data we need that the JSON does not contain out-of-the-box, serialize that into an XML object and then run an XSL transform against it to get our final XML. Performance is not really a concern, so the dynamics made it quite easy to do. Beyond that, I'm totally with you.... I don't recommend using them. As always, great video! The Python thing, while disturbing, was pretty cool. I didn't know that was possible.
100% agree :-) Was going to write something similar.
there is JObject
The lack of IntelliSense is the main reason why I do encourage people to use TypeScript in almost all JavaScript commercial projects (even for non-commercial little projects it's good choice tho). I just cannot see (even small but) scalable app, without IntelliSense and error checking in IDE/Compiler/BeforeRuntime. It's definitely the one of the possible reasons to project's failure
Typescript makes git merges way less painful thanks to type checking, definitely useful to try to enforce code correctness
When I read the title I wondered what you had against generic. I had no idea this was a thing....and I'm gonna go back to that now.
I had that thought for a moment too, and I know about dynamic. Had pushes it sooo far to the back of my C# knowledge bucket 😅
The JSON case was the exact reason I ended up using dynamic, and it has been on my mind whether to move away from using it, as it is used in a production service. This completely answers my question! Thank you!
Thank you for this breakdown on dynamic. I like your videos, your practical approach really helps to understand these features.
Would you consider doing the same on ref and out keywords (parameters)?
I absolutely have videos coming for those topics. Stay tuned
It is probably worth writing a DTO with just the fields you want to read. Maybe it takes a tiny bit more time than a dynamic type, but you don't have to wonder every time you access the object what are the available fields.
☝
In my whole career as a C# developer & PM, I just had one project, with one usecase which justifies the usage of dynamic.
I told my Staff, that, when they think, dynamic is necessary, they do it probably wrong and it's more likely, that they have a glitch in their design.
Curious what was the usecase?
@@lizard450 As part of a product database, I recognized the need to map the properties of the articles not in static tables (SQL) and corresponding C# objects, but to give the user the possibility to create parameter sets.
These sets are defined once with their properties and structure and can then be used for other articles of the same type.
However, it was necessary to use specific data types incl. type-related validation for the respective attributes.
Since the attributes essentially all have the same structure, I did not want to implement specifically against the data types.
So no Attribute_Int, Attribute_String etc.
That would have meant type checks and/or casts in too many places for me.
I preferred to have cleaner code, I gladly accepted the performance penalty.
Therefore there is an interface "IAttribute" with the dynamic property "Value".
I know it sounds strange but when you see the project and the high degree of dynamics and flexibility you'd understand ;)
@@TuxCommander thank you very much for your reply. It does sound strange but I do appreciate the effort. I think in your situation there I'd have used json and the value would just be a string. Who knows maybe even TSON
@@lizard450 plesure ;)
Yeah, I know, sounds odd and is hard to explain but json or storing the values as string was not an option due to binding in WPF and dynamicly generated UI elements as well as calculations/comparisons which needs to be perfomed on the attributes and not to mention the export features.
This would have caused to many explicit casts and validations.
Actually the dynamic type helped here a lot in having a clean code.
Even I was not happy with it in the first place from from the performance perpespective but also this is managable and goes under in the rest of the app actions.
The App is in total quite fast and responsive that you would not expect its that structured under the hood.
"Not everyone knows about this feature, and that's good..."
Ha, I felt that.
I think C++ developers also would say that :-)
@@igorthelight I don't know, in a lot C++ those unknown features tend to only work for the specified purposes, (though I suppose you could say easily misused, but not really fair when everything in C++ can be so grossly misused, not just hidden features) whereas dynamic addresses a problem that's better solved without it. (the only real reason to have it in the language anymore is for backwards compatibility)
@@Spartan322 Agree.
But "dymanic" is useful for a few things like MS Office integration and maybe some other stuff.
But I agree that we should use it as rare as possible. It's slow and errors are harder to debug.
I mean with JSON u can deserialise to a JsonObject and then do .GetValue and it would probably be faster. But dynamic does have a use case for the once in a million situation and should not be undermined
I suspect you knew everyone watching this would be interested in that last use case.
You really roasted this one. Well played :)
You brought me old memories of the old Signal R, where I had to use dynamic. I am super happy that I do not have to do it this way anymore.
I am watching your videos for a while already to improve my coding skills and/or get to know about new features or oppinion on coding styles/habits.
This video was quite special for me though. The moment you typed your github account URL I was like "Wait a sec, is that the Elfocrash for real"? And yea, you are. I am big fan of Lineage 2 Java server emulators for like 10 years already and I have seen some of your work as well. Kind of nice discovery. World is really small.
dynamic was added for a couple of reasons: 1.) VB - (not VB.NET) is all dynamically type. The var keyword was also borrowed from VB (to make C# look more friendly to VB developers - but var in VB and var in C# are totally different). MS wanted to encourage more developers to move from VB to .NET. Same reason for having ViewBag. In the old ASP this was used, so some people thought is should be there in ASP.NET as well (ViewData is a little more structure alternative) 2.) Office / COM interop is actually somewhat easier with dynamic. 3.) JavaScript / Python are dynamic languages. As JavaScript got more and more attractive for developers, MS wanted to add "stuff" to .NET to make it easier for JS / Python developers to migrate to .NET. It was always a problem for MS to establish new technologies. The old stuff worked usually quite well and developers would not migrate. So new developers would gravitate less and less to the MS platforms. The challenge is: developers are just as emotional as other humans are. If data scientist hear that Python is the go-to language now used by everybody - they use it. Even though Python is terribly slow, has some odd syntax (not as bad as Perl), dynamically typed (which is B.A.D. by design) and is just as hard to learn as C# or Java. You can see these things in many areas. Why does hardly anybody use the preprocessor in C# code (besides #ifdev DEBUG) - well the C# community doesn't do it. But in C++ everybody uses the pre-processor. You are no real C++ developer if you don't use the pre-processor (you have to for #include). Another example is the syntax of PowerShell. Kind of similar to Perl. You guess why... These things keep repeating and are usually driven by business decisions.
I have used it for a dynamic api for automated tests to great effect. Not many use cases but when one comes along it's super well implemented and an intuitive language feature.
What is the performance comparison between a dynamic object and a dictionary for example?
So dynamic method calls have something I think is called Double Dispatch, which is useful for a visitor class without having to write accept methods on all of your objects.
So say you have a heterogeneous list of objects, and you want to call different visit methods based on their runtime type. If you just call visit on the object, it gets statically bound to the overload that takes object. But if you first cast the objects to dynamic (and/or the visitor I think), then it will call the most specific overload possible based on the runtime type.
Then the pattern becomes just add another .Visit overload for each new type you want to handle, no other boilerplate code required. It even works to subclass the visitor.
I have a helper class in my code where I use this specific mechanism to return true or false depending on whether a variable is a generic IList or not :-)
Nick, I think your recollection of why dynamic was introduced is a slight bit off. The keyword was a side effect of Microsoft's work on the DLR - Dynamic Language Runtime, not the end goal. DLR was an effort to enable dynamic languages (Python, PHP, Perl, etc...) to target the .NET. Once DLR was made available, C# was able to take advantage of it by introducing the dynamic keyword. Keep up excellent work.
This is correct. IronPython and IronRuby are implementations of other languages which can compile down to MSIL to interop with other .Net languages in the same way that you can access VB.Net or F# from C#. It shouldn't be thought about like the introduction of Records as a part of the language, instead it is more like the introduction of var to make LINQ work. Unlike var, dynamic isn't as valuable for wider application, but for the specific use cases it supports it can be invaluable.
Viewbags were also my first exposure to dynamics.
I went out of my way to convert everything to using the explicit model objects, but I think MVC 5 was a requirement for that....
it was at least 6 years ago now.
The dynamic type is a great obfuscation tool.
I agree with you about NEVER using dynamic - right up to the point I found a project where dynamic made complete sense because of the coding simplicity that resulted. I now ONLY use it ALLWAYS in conjunction with new C# functionality such as "if(x is type y){dosomething(y)}" and "var allvariables=dynamiclist.Where(q=> q is is Variable vv);" and so so on. BTW The project is a general parser for translations between different computer languages. The source code as a string list was converted to list of records of type Variable, Keyword, Operators etc. - the complete tokenised source code all now stored in a single dynamic list rather than a string list.
I am using dynamic to get dynamic result from database -> odata api -> power BI. Works great, since i cannot define static model for some queries, otherwise the powerBI would be painfully slow.
Yea was just about to say this. Dynamic typing is important for dynamic queryable apis like odata or graphql
For Json APIs, you can also use Edit->Paste Special->Paste JSON as a Classes, at least in Visual Studio (I assume Ryder has the same feature). That creates the necessary classes for you automatically.
Sure but the thing is that when I'm prototyping I don't care enough to build POCOs and do serialization. Just wanna integrate with the thing. There are actual proper JSON API libraries that provide the appropriate wrappers around the core contracts and take care of all the linking, pagination etc so in that case I would use that instead.
Using this to work with dynamic Office objects was nice, and a runtime hell at the same time.
Using it for IronPython is a valid use case, since many mathematicians will build their data analysis with Python und NumPy, and then hand off their big data or data analysis project written in Python to you for "integration".
One use case where I‘ve encountered dynamic, is to have runtime polymorphism for method overloads. Method overloading normally leads to early binding, but when you cast an object to dynamic before passing it as a parameter into a method, the decision which method to call will be made at runtime, based on the object type.
i think that a generic would be better for that use case
@@hck1bloodday That depends on the use case. First problem is, you cannot do method overloading based on generic type constraints, try it. You can only define one generic method and then overload it with specific types. Even then, the problem with the approach will be that the method binding will still happen at compile time, meaning that concrete types can be hidden behind more general types and a method with the more general type will be picked by the compiler. Sometimes you need the polymorphism at runtime.
@@leonardkupper7250 I will try that, may be using a genérico with interfaces instead of concrete types could solve that, I'll be back here with the results 👍
I’ve found that if you cast dynamics to an IDictionary, it makes them a lot easier to work with
Another scenario where you might have to use dynamics is when using reflection. If you need reflection, use object wherever you can, but sometimes the code you're trying to invoke just won't accept the object type and you'll have to pass your object, which is already the required type and simply cast to type object by reflection, must be passed by casting to dynamic.
If you still want to double check what you're working with you can use the methods reflection offers to double check.
20 seconds in and I'm applauding you
Nice one Nick, keep them coming :). I agree the use case for dynamic is limited. We use Jint (Javascript interpreter) on one of our projects and this is one of those use cases as you are traversing across language types and who am I to question a wizard like Sebastien Ros.
Dynamic/scripting languages are very powerful and most often they offer intellisense also. C# DLR is written on CLR that's why it is slow. At runtime, the dynamic code is translated into DLR and then compiled and executed and that is a performance killer.
C# intellisense is also written for CLR but they could have made it available for DLR but they did not.
In the old days, foxpro was a dynamic language with speed comparable to C language. It was very easy to design application frameworks and ERP software in it.
But it took them ages to introduce dynamic keyword in c#, prior to that they wrote tons of code to create dataset code in order to handle a variable number of data fields.
Nick, would you consider having a shortcut key indicator superimposed in the corner of your screen, occasionally I see you using a specific shortcut combo that I didnt know existed, would be handy to simply re-watch the video and see the actual keys pressed.... Just an idea anyway, I've seen other coders do this as well.
I think Rider has a plug-in for such presentation. I just have to find a way to make it not invasive because it can get annoying for me when I’m making the video
@@nickchapsas ah, I thought it was recorded in the background and then superimpose on top of the video after.... if not, then yeah, that'd be annoying.
I agree with you, but the dynamic type saved me one time adding a new app that later turned into a feature in an app at work. Short summary, business changed the requirements multiple times while we were implementing. We ran into so many issues on the server code, but I decided to use dynamic to speed up some of the changes. I added the appropriate unit tests and integrations to be sure it wouldn't break. It's touchy because if someone adds something new and doesn't add new tests it could break, but it saved us a lot of time. A refactored would've really delayed us even more back in the timeline that the business had already caused.
That was also the time when Microsoft had quietly decided that .Net was the past and Visual C++/Javascript was the future because web. I went to Build around then and ALL the sessions were around "how to move from .Net to C++/JS and switching to WinRT (UWP) which was going to replace .Net with a new architecture based on C++ and JS. JS is an inherently dynamic language (one reason I loathe it so much). This was when Win 8 was coming out at well and I remember at the time that a lot of us noticed that the announcement of UWP didn't mention .Net at all - and the response from Microsoft was bizarre - that we'd learn more close to the release date. In fact, it seems that Microsoft threw together a bridge between .Net and WinRT because a lot of stuff in WinRT was missing or cripples in .Net at first. The other bridge was to add "dynamic" so interop with WinRT JavaScript could work.
In the end, WinRT and UWP tanked big time and the idea of writing apps for Windows in JS just never happened. But we're still stuck with "dynamic" which fortunately, most C# programmers never use.
Good one Nick. Minimum size for an object(ref type) on a 32-bit machine is 12 bytes (8 bytes overhead+4 byes to store info). Class MyTest { public dynamic field=(int) 100 ;} even in this case it won't consume 12 bytes (including 4 bytes int field) for an int value instead the 'field' will be treated as an object because of dynamic and thus the size will be : 12 bytes (MyTest class) + 12 bytes (for the dynamic field) = 24 bytes. So in a performance / resource intensive system it's a complete no-no.
Intellisense hates dynamic, because it even don't know what the hell is going on. 😅😅
I use dynamic for COM interop because the COM objects have vital fields and methods I need to use, which aren't showing in the static types. The only other way to do that would've been heavy use of reflection. Wouldn't be more stable, cleaner or faster...
Hi Nick, please make a lecture on Expression Tree.
You didn't touch on reflection based features and using dynamic over the reflection APIs. Do you think there is any value there?
I use ExpandoObject to dynamically add properties from a source object, i.e. to support the "fields" query parameter for a REST API. So you can do "?fields=id,name" and the API will only return the id and name fields of the requested resource.
You can get Querystring variables fed directly into your RESTful API function with little effort. Unsure why you'd use ExpandoObject for this.
@@briankarcher8338 What has this to do with what I wrote 😅
For your usecase... is there a reason you didn't just deserialise it as a JObject instead and access "followers" as a JToken?
You can also parse response from last example without using dynamic and without creating extra classes, you can use something like:
var jObj = JObject.Parse(response);
var followers = (int)jObj["followers"];
What's people's fear of creating a data class? Strongly typed variables alone makes it worth it. And if you're using C# 9 you can create a record to make it even easier.
Edit - Regarding the end of the video, you can create a partial contract to get just the data you need.
I was working with serializing and deserializing the other day, and this would have been a really easy way to get the object parsed and passed between functions, of course, I'm not mad that I found another way around the issue.
But what I really needed was to find a way to **Cast** an unknown variable to a type variable, and the compiler wasn't having it.
So I had a variable of the type "Type", and the compiler told me that I was using a variable like a type, but that is because it is literally a **Type** variable.
What is the comparison between dynamic and reflection for performance and readability?
Couldn't agree with you more about all your points here. I, too, was always thinking to myself "I'm not gonna use this ViewBag, why would I when I can use the ViewModel?". Also, when I see "dynamic" in someones code, I immediately think... okay, who was being lazy here? lol
Hey Nick, can you make video on DI with singleton? Do we need to check for thread safety while using singleton or its taken care by default by AddSingleton ?
Is there any alternative to dynamics in situations similar to:
private static T GetSum(T x, T y) where T: struct, IComparable
{
return (dynamic)x + y;
}
I have situation which is more complicated than this, but main problem is that I want to use arithmetic operators in generics where I know that generic type have those operators.
@@deidian635 My use case is bit more complicated then this example.
Making different methods for each datatype would lead to significant duplication of the code, where just small part is related to dynamics. And I would need to write at least 3 versions (long, double and decimal).
It would be really nice having some way to constrain types of generic to ones with arithmetic operations.
@@deidian635 C++ have feature which I need here:
template
void Deposit(T t) {...}
@@deidian635 Compile can easily optimize those calls. Every time + operator is called it can replaced with appropriate add assembler instruction if final compiled version of the code for every primitive type. It would be almost zero performance hit. My whole point is that there should be a way to constrain generics to arithmetic types. C++ constraint is compile time checked, after that it is using normal arithmetic operators as they would be normally used. There can be even a keyword which can say that type is arithmetic (as we can constrain it to class or struct).
Hey Nick,
Am very glad to see the real use of dynamic.
Even one of my project I really used it for the same purpose. But in my case is little different .
I read the database result which is multiple resultset, and the number of resultset is varies depending up on resource. And the result set order also vary depends on the what data is available. so I can not use the POCO to bind the data. This is where I used dynamic with some logic in the resultset columns.
Do you suggest any other alternative I can try?
I use dynamic for Excel Interop.
I could use objects but you have to typecast everything.
Dynamic prevents that.
Office interop is the absolute perfect usecase for dynamic.
Office interop with dynamic is a helpful last resort but usually only truly needed if your users are operating across very different versions of office PIAs versus the ones compiled with the project. If that's the scenario though, dynamic often ends up kicking a problem down the road rather than fixing it.
Dynamic can come in handy when doing things like metaprogramming but other than that I struggle to find a usecase. Even for things like prototyping I tend to just build limited pocos or generics
Only use i had was to transform a few props in 100 000 json objects stored in a DB. Json objects where made by 3rd party so i did not care or know the full schema of the objects, just for the props i needed to fix.
I agree that dynamic can be neat for quick and dirty prototypes, but as for JSON, why not just use JsonDocument? (From System.Text.Json)
For the same reasony why I wouldn't use JObject or any other wrapper around the json object. During prototyping I want to get to the finish line as quickly as possible. If that Having to deal with parsing and root elements and try get values is not something I wanna have to do. Simply traverse the json object as if it was part of the code.
Thank you Nick! Great content, never heard about IronPython before. I see it's still a maintained project, so there must be some use cases for it. Just wondering how this compares to C# scripting...
What's with reflection?
One decent use-case for dynamic is the ability to use JSON objects without writing class definitions for these objects. It's not a GREAT idea to use in large scale enterprise applications, but it's great for small one-off console applications. This also can handle changes to the underlying json object as long as the elements you are accessing weren't changed.
I guess you didn't watch the whole video :D
Sitefinity CMS makes heavy use of dynamic. Admins can define new types in the CMS admin panel and component cshtml templates get an object with a dynamic property called "Fields" to access any custom properties. The whole thing is very interesting
Thanks for the breakdown.
Another cracking video
In last the usecase we can use jobject of newtonsoft, maybe we should compare the performance
14:13 "Why I don't use them, and why they don't have a place in my code." ...except for an obvious use case that mirrors what so many are doing when it comes to consuming API.
I think union types is another use case as to why you'd want to use dynamic. I'm not super happy that I do but basically it either use dynamic or use recursion which I think kills performance as much as dynamic does.
Event the example that you showed I think that JObject or a Dictionary would be faster, wouldn't it?
In 12:09
Dynamic in that case is actually a JObject which gives direct access to the json properties. Explicitly specifying it would be faster in code but slower for rapid prototyping. When I’m creating a prototype I don’t care about performance
@@nickchapsas Ummm, interesting, I didn't know that, I thought it was like a dictionary
@@lmtr0 No it's JObject but JObject itself implements IDictionary so it kinda is a dictionary by proxy
@@nickchapsas ummmm, ok, that's something I am gonna have to take a look later. Thanks for the info. Likewise I usually use JObjects because I don't really like to loop thought a dynamic object
The python example really is cool. But dynamic seems to be a pain in the ass to debug.
There are times it actually can work faster. I ended up using when I had no idea of what data type I was going to have. Then I passed the dynamic type to an ODBC parm.
personally using dynamic to have UI (de-)serialization
That way, no strict rules have to be followed when serializing those to json
it is quite handy for very, very specific usecases
Nice explanation. I am using elastic to search across multiple indices to return different schema types. I am using dynamic return types over . Would love to know your thoughts?
I use it in dapper for sql return types, I don’t see why not to use them.
Ultimately it is because of contract safety and performance. Contract safety in this case is the least of your concerns so in my case it would be performance.
It just feels like syntactic sugar for accessing a nested HashTable without checking for key presence. For the python example, returning a Dictionary at least would allow you to easily enumerate it.
is dyamic type good for malware?
I sometimes use dynamics within a method, but I never let them escape that context. Tuple return types work much better for that.
im glad the only use case i used for dynamic is the one you showed haha
It's good when you use bridge to translate to JavaScript. That way you can write native is from csharp.
The good use of dynamic or just a simple implementation as ExpandoObject is for rest api calls like you showed. BUT... Not when you have an obvious response which you can easily create a poco for but when you have really DYNAMIC data/response and you need to hold the values. For instance I can get the same data from a sensor but different sensors might have different json models. So I can't specify a poco. I need dynamic dictionary like ExpandoObject provides and create models on the run. Especially good when the infrastructure comes from a client and is existing one. I agree that this might not be the fastest but just parsing small chunks of sensor data is not really that demanding operation. Also it allows to work with nested levels within json which is the usual case. One level json is the best shape but we rarely see those in real commercial apps, don't we? One more good thing about ExpandoObject is that you can write extension methods for it which you can't for 'regular' dynamic type. It is definitely useful but not exactly for writing calculator or calling external api for response you know model of up-front.
The only time i'm using Dynamic was when using al lot of run time loading of libraries and when calling IronPython.
I had to use it because of a complex architecture I was trying to use inheritance for. It wasn't easy to type cast so I used dynamic
Hey Nick! Any plans for a IL video? It's nice that you highlight a topic that few people talk about
IL is such a hard topic to talk about because it is so disconnected for regular C#. I am planning to talk about it a bit more on a video about Lowering but I don't think I will ever be making a dedicated video on IL.
I only use dynamic to return temporary Linq selects... But only on scope of a method...
I use dynamic to pass parameters to stored procedures with generic methods wrapping dapper.
var parameters = new {Fullname = "Ibrahim Hussain", Gender = "Male"};
And pass that as dynamic parameter to the db call method.
This is not dynamic, this is an anonymous object type. It’s quite different
You may use it when loading(sp, new{},connstring);
@@nickchapsas yeah. I can pass the anonymous abject to a method parameter that accepts dynamic. Prevents me from having to use a different model each time I need different parameters
@@ibrahimhussain3248 Yeah so that's fine because the method has it as part of it's API as dynamic. You didn't use dynamic yourself, but rather Dapper accepts it. That's totally fine.
If you use "dynamic" only for the JSON objects, then isn't JObject enough for that? You can take any property from JSON without any POCO object.
Using JObject directly would be the "correct" way to do ti but it doesn't provide the same developer experience. I just wanna traverse the path of the object in C# without having to deal with GetValue() methods and .ToString calls. The whole point of using dynamic in json is to skip over all that noise. Side note, dynamic in that context is of type JObject. It just gives you access to the json fields without having to go through the methods.
@@nickchapsas I'm not sure about C#, but in Java with Jackson library, there's a way to just throw away all unknown properties not defined in the object, so in your case, you could have a class that defines only followers property. Simple googling tells me about the MissingMemberHandling setting in Newtonsoft.Json. Not sure if that's performant or not, but this way, you get compiler checks and IntelliSense, which to some degree worth it?
@@Brawaru Newtonsoft by default will do that as well but if you have nested objects you still need to provide the class structure which is tedious. You cna technically "reroute" a property but that's too much work for a prototype.
Dynamic has its place, and can be crazy useful. The main value comes when a consuming layer needs to add unforeseeable information or behavior to a fundamental class. Without dynamic, your only options are inheritance or interfaces to try to extend the core class. These methods aren’t always the best route, as the base class might not be aware of the extensions to be able to gain value from them, but a dynamic base class CAN understand that dynamic extensions are expected to exist, and can act on them. This works very well for sharing data models across layers where, for instance, the UI is determining additional property values to store on a record. If you use a no-sql store, then it’s easy to store and retrieve these values by a base framework without ever needing to extend the framework. Just one example. Also, if you’re building a WPF app, dynamic properties are also bindable in XAML, which is really handy - and this can include Command properties. So instead of building new class systems for View Models to extend your data models, you can simply “aspect” behaviors onto the data models, depending on the view, to get the behavior the view needs. And you can do this in a structured way, so while the end result is a dynamic type consumed by the view layer, you still have structured, testable code.
Ah yes, the "covering all your bases" method signature: static dynamic!
Wrong title or did you change your opinion?. You said that you don’t use it in the beginning and in the end you said that you use it. Be consistent. That said is good that you mentioned when to use it and when not.
Well using it in non-production code explicitly for rapid prototyping, so it's only in code that will never see the light of day. When I say "never" i am only referring to code that other people are meant to see. When you're writting code that only you will see then you can do whatever you want, really.
Hah, I couldn't help but laugh at "I won't explain what COM is," because that would easily have taken the remainder of at least this video... Also though, it's arguably IUnknown too. :)
Domain Specific Languages was a thing for a while. I think that was one of the reasons they thought this was all a good idea.
"Yeah, the thing that you just typed? That's fine." 😆
It's useful with Dapper
Dynamic is useful for SQL, but after that I really see no use in it
10/10 : devs are way too comfortable with dynamic and don't understand the importance and implications that come from using it
JsonDocument now exists in System.Text.Json so even the json use case shouldn't be a thing
I have to deal with dynamic and viewbags nearly on a daily basis...and I can fuckin confirm it is a pain in the ass.
Never understood why one would use this and still don't xD
Runtime expections... just like... MediatR... ;)
You really did IronPython dirty. I wrote a whole automation suite that was scriptable with it. I didn't have to use dynamic at all, because a static class with Func properties defined all the extension points and the parsed script was expected to have top level functions of the same name. Anything that didn't match were just left null and not invoked. So the C# code was treated as the protocol for the Python script, while your Weird example does it the other way around which is definitely untenable. I wonder if this difference is why I don't share your disdain for IronPython.
(btw these days there is also JInt that does modern Javascript, it's used in AngleSharp and Orchard among other things. So it's not a dead use-case as you suggested.)
Fun fact, it also completely breaks Extension Methods
Microsoft use dynamic in the azure documentation to inject cosmoDB in your azure Function
tho dynamics are useful against always changing graph rest api like facebook api.. at least to test and try stuff..
@Andrew Ramshaw haha you dont understand my point :) ... i also prefer an oop mapping layer
Me, a JS dev, pretending I have any idea what's going on: 🙂
I hope your life is going to get better soon...
Roasted™
Try TypeScript - it will save your sanity ;-)
👍🏽
Old good ViewBag :D
Dynamic has its uses, specially when processing numeric data.
Assume you want to perform a numeric operation on a list like standard deviation or mean squared error.
Yes , you could check the type and have a different code set for each type ( float, double, decimal , int , unsigned int).... or you could use dynamic. A lot cleaner and concise.
An even more complicated case would be if a formula could receive a combination of double , decimal and integers. Not a common case but it can happen , for example if you are working with a database and are doing a reporting tool.
Dynamic is the perfect tool for runtime evaluation along with c# script.
Nowadays you just dump the template of the JSON into a website and it spits out your poco object. So I don't use Dynamic for your use case anymore.
with JSON i would use JObject
I have never got it to work. I guess I have been spoilt by Python an JavaScript 😅
Most of your other videos are very good. But here, you entirely missed the point behind dynamic / DLR. Dynamic was not introduced in C# to solve a problem in C#. It was introduced in .Net (not C#), primarily to allow scripting languages to run inside a .Net process and access the .Net/C# stuff running in this process. In other words, to allow running Python/Ruby/Etc. scripting code in .Net. Many scripting language are not typed and the compiler safety you are talking about has never really be a problem in those languages.
You are mostly talking about the dynamic construct in C#. This is no more than synthetic sugar around the DLR, basically a side effect, which happen to elegantly solve few edge cases in C#, one of them being the COM interops. I would not use dynamic to call C# code from C#. That's not the purpose of dynamic. Dynamic is there to allow C# code to call objects, who's members are unknown at compile time, e.g. scripting objects or objects based on data. In this case, the runtime will actually ask the object for "what to do" (which the C# objects in your example have no clue about those dynamic methods), and then the dynamic runtime will fallback and use reflection on the C# object to invoke the method. This use case makes no sense. The expando object in your example is an exception in your example.
Finally, about performance. Dynamic will be slower than static! And the examples in the video will be extra slow, as they are not real dynamic objects, but objects where the runtime emulates the dynamic behavior. A real dynamic object will emit just-in-time generated code to "glue" the dynamic call to the real implementation of the method logic. Depending on the quality of the object, the speed of this code will vary. Good quality code will be 2-3 slower than a normal C# call. But keep in mind, this overhead only happens when you transition from an object implemented in C# to an object implemented in Python or Ruby (or vice versa). The benchmark you provide are not representative for the intended use case of dynamic.