Am I doing something wrong, or is the following code really not possible?
dynamic x = new ExpandoObject { Foo = 12, Bar = "twelve" };
If this really isn't possible, is there another one-line way to instantiate an ExpandoObject with two properties?
Why would the C# team opt to disallow the same initialization syntax as for regular objects, anonymous objects, and enumerables/lists?
Update
I asked this question because I was trying show a Pearl enthusiast the cool new dynamic features of C#, but then I was stalled by not being able to do what I thought was a logical instantiation of an ExpandoObject
. Thanks to Hans Passant's answer, I realize that ExpandoObject
was the wrong tool for the job. My real goal was to use the dynamic features of C# to return two named values from a method. As Hans points out, the dynamic
keyword is perfect for this. I didn't need an ExpandoObject
, with all its overhead, to do this.
So, if you want to return a pair of named values from a method, and you are not concerned about type safety, Intellisense, refactoring, or performance, this works quite nicely:
public dynamic CreateFooBar()
{
return new { Foo = 42, Bar = "Hello" };
}
Usage:
dynamic fooBar = CreateFooBar();
var foo = fooBar.Foo;
var bar = fooBar.Bar;
Am I doing something wrong, or is the following code really not possible?
It's really not possible. The thing on the left of the assignment operator has to be a property or field known at compile time, and obviously that is not the case for expando objects.
Why would the C# team opt to disallow the same initialization syntax as for regular objects, anonymous objects, and enumerables/lists?
The way you phrase the question indicates the logical error. Features are not implemented by default and then we run around disallowing almost all of them because we think they're a bad idea! Features are unimplemented by default, and have to be implemented in order to work.
The first step in implementing any feature is that someone has to think of it in the first place. To my knowledge, we never did. In particular, it would have been quite difficult for the person designing object initializers in 2006 to know that in 2010 we were going to add "dynamic" to the language, and design the feature accordingly. Features are always designed by designers who move forwards in time, not backwards in time. We only remember the past, not the future.
Anyway, it's a nice idea so thanks for sharing it. Now that someone has thought of it, we can then work on the next steps, like deciding if it is the best idea upon which we can spend our limited budget, designing it, writing the specification, implementing it, testing it, documenting it and shipping it to customers.
I wouldn't expect any of that to happen any time soon; we're a bit busy with this whole async-and-WinRT business that we announced at Build last week.
There's a better mouse trap than ExpandoObject. The dynamic keyword handles anonymous types with aplomb:
class Program {
static void Main(string[] args) {
dynamic x = new { Foo = 12, Bar = "twelve" };
Display(x);
}
static void Display(dynamic x) {
Console.WriteLine(x.Foo);
Console.WriteLine(x.Bar);
}
}
One unfortunate problem is that the C# compiler generates the anonymous type giving the members only internal accessibility. Which means that you'll get a runtime error when you try to access the members in another assembly. Bummer.
Consider a tuple, much improved in C# v7.
Dynamitey (open source PCL and found in nuget) has a syntax for initializing expandos that can be inline.
//using Dynamitey.DynamicObjects
var x = Build<ExpandoObject>.NewObject(Foo:12, Bar:"twelve");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With