.NET/C#/VB.net: some links on ExpandoObject
Posted by jpluimers on 2013/10/10
Still a C# 4.0 / .NET 4 feature that I need to investigate more deeply: ExpandoObject, partially because I had very bad memories of Variant support in Delphi.
So here are a few links.
First of all: since VB.NET already does late binding with the Object keyword, you cannot use ExpandoObject with Strict On in VB.NET 10.0 and up:
- vb.net – .NET 4.0 framework dynamic features in VB with Option Strict On? – Stack Overflow.
- VB.Net equivalent for C# ‘dynamic’ with Option Strict On – Stack Overflow.
Now the C# links:
- Adventures with C# 4.0 dynamic – ExpandoObject, ElasticObject, and a Twitter client in 10 minutes – CodeProject.
- c# – What are the true benefits of ExpandoObject? – Stack Overflow.
- Dynamic in C# 4.0: Introducing the ExpandoObject – C# Frequently Asked Questions – Site Home – MSDN Blogs.
- ExpandoObject in Csharp 4.0. Its really dynamic | LinkedIn.
- What are the true benefits of ExpandoObject? – Stack Overflow.
- Dynamic Behaviour on Objects at Runtime With Custom ExpandoObject – CodeProject.
–jeroen






abouchez said
I find variants pretty powerful in Delphi.
At least when you consider that they were almost always there, whereas dynamic typing was available in C# only since 4.0 revision of the framework.
You can add your own custom variant type, by defining some TCustomVariantType and TInvokeableVariantType inherited classes. Those classes show all the things a class would have to do to be able to be used (not just stored) in a Variant, without necessarily implementing IDispatch.
For instance, you can easily code something like this (which is pretty easy to work with):
var Customer: Variant; begin with Props.Execute( 'select * from Sales.Customer where AccountNumber like ?', ['AW000001%'],@Customer) do while Step do assert(Copy(Customer.AccountNumber,1,8)='AW000001'); end;Custom variant types have some performance penalties, but which may be circumvent with some low-level hacking – as we did in http://blog.synopse.info/post/2011/07/01/Faster-variant-late-binding
jpluimers said
I disagree, but that is OK.
I’m more of a statically checking person.
Off the record remarks made clear that variants is one of the aspects that Anders Hejlsberg is definitely not proud of, as is the support for the dynamic keyword in C# because of the same reason.
But I do get you can do some nifty things with variants (and dynamic).
A. Bouchez said
Yes, the Delphi variant type was close to the COM variant type, with some particularities… so it was “VB-like” at this time.
Far away from all the features available in C#, but nice enough to allow dynamic attributes and some duck-typing features.
Joseph said
>You can add your own custom variant type, by defining some TCustomVariantType and TInvokeableVariantType
>inherited classes. Those classes show all the things a class would have to do to be able to be used (not just stored) in
>a Variant, without necessarily implementing IDispatch.
That’s the frustrating thing, that it isn’t list a true dynamic variable and once you “stray off the path” a bit you’re looking at lots of code to do simple things, like here and here:
http://stackoverflow.com/questions/10314757/delphi-converting-array-variant-to-string?rq=1
http://stackoverflow.com/questions/8925317/how-can-i-convert-from-generic-to-variant-in-delphi?rq=1
@JPluimers
>I’m more of a statically checking person.
So were lots of other famous people before they tried dynamic-typed languages and changed their mind. :-)
http://www.codinghorror.com/blog/2004/09/loose-typing-sinks-ships.html
http://wayback.archive.org/web/20040119101456/http://www.mindview.net/WebLog/log-0025/
>But I do get you can do some nifty things with variants (and dynamic).
The best thing of all: no more
queryResults.FieldByName(‘Total’).AsInteger !!!
Instead you can build a nice object with the return values and just use
queryResults.Total !!!
Dynamic typing eliminates one of my greatest frustrations! :-)
Also imagine a function that can take any CSV file with a header and return an object that maps to the field names (plus, say, next and previous methods) and let you navigate any CSV file with ease.
Actually the next best thing to easy-to-use database/CSV objects are simple dictionaries that aren’t limited to a single value type. Once you use these, you see that they can be used EVERYWHERE. For instance, program settings can map to a dictionary:
settings = {‘start_path’ = ‘c:\whatever’, ‘delay’=5, ‘save’=True}
In Delphi we’d use a rigid record structure and then if a new parameter were needed we’d have to change the record definition and the code to both read and save the new record. This way you’d need no code changes at all, if settings were just read from a file and added to the dictionary!
Python actually uses a dictionary to hold all the properties of an object (key=name, value=variable value or method), of a class, the global variables/functions, local variables/functions, etc. And that makes doing crazy things easy. :-) Tweak a class definition, build a class from scratch with a dictionary, add properties to an object, etc.
You also gain duck typing, which is very nice. You can pass a function expecting a file object something that say, has open, read, write, close methods without having to subclass from a TFile-whatever or implement a special interface, etc.
As you can probably tell, I’ve become hooked in the last few months. :-) Implementing dynamic in delphi is on my long, long list of features I wish Delphi had, although I expect a lot of them will turn up in DWScript first (several already have).
jpluimers said
Actually I am doing DWScript stuff, so I am used to more dynamic things (:
You name a lot of interesting points, and given Ruby playing around I did, it only worked for me with a lot of tool support (scaffolding, really intelligent code tooling and rigorous testing) to make the most benefit.
–jeroen