Instantiation with C# "dynamic" Keyword - c#

I've seen many examples of this tool which abstracts away the cumbersome syntax of Reflection. However none demonstrate instantiation of an unknown type. Is it safe to assume this isn't possible with "dynamic"?

Logically, it's impossible to instantiate an unknown type -- to instantiate a type, something must know what it is.
dynamic is useful for manipulating values of an unknown type (by assuming that it is capable of certain operations, which will fail at runtime if they are in fact not possible). To instantiate any type, however, you either need to use compile-time instantiation (e.g. using a C# constructor call), or else you need an instance of Type that corresponds to your desired type.

The compiler can use the dynamic keyword so that the dlr will construct a type, but it's designed to late bind the arguments of a constructor rather than the type to be constructed. The opensource framework ImpromptuInterface abstracts the dlr calls, including the constructor. If you need to call a constructor that has arguments this will run about 5 times faster than using reflection/Activator.
var x = Impromptu.InvokeConstructor(Type.GetType("SomeType"),args...);

I don't know what your goal is... but do you mean something like
dynamic X = Type.GetType("SomeUnknownType").GetConstructor(null).Invoke(null);
?
the above just calls the default (parameterless) constructor of the Type "SomeUnknownType" and assign the resulting instance to a dynamic .

Related

List<dynamic> elements have fields but I cannot access them. Why?

I need to loop over a List<dynamic> objects.
The list's objects all have values, but for some reason, I am not able to access any of the dynamic object fields. Below is a screenshot of my debug window:
There you can see the object contains fields (such Alias, Id, Name, etc).
I tried both casting it to a IDictionary<string, object> and ExpandoObject, to no avail. I did not face such a thing before: failing to access existing fields in a dynamic object when they exist.
What is wrong here?
The code is throwing a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException with a message stating {"'object' does not contain a definition for 'Name'"}.
The list was created adding anonymously-typed objects, like this:
return new List<dynamic>(fields.Select(field => new
{
Id = field.Id,
Alias = field.Alias,
Name = field.Name,
Type = field.Type,
Value = field.Value,
SortOrder = field.SortOrder
}));
where fields is an ICollection<Field>, a strongly-typed collection.
The telling part is the exception:
{"'object' does not contain a definition for 'Name'"}.
This indicates that the runtime binder was not actually capable of accessing the type you're passing in dynamic (since dynamic does actually enforce visibility rules).
The most likely cause of this is that you're creating the anonymous type in a different assembly from the one where you're subsequently reading it - since anonymous types are declared internal, the consuming assembly cannot access it, causing the error message above.
Contrast with the usual case of runtime binder exceptions:
'<>f__AnonymousType0< string >' does not contain a definition for 'Name'
EDIT:
A possible solution to the problem is to use the InternalsVisibleToAttribute on the assembly containing the anonymous type. However, this is code smell - just like any other use of InternalsVisibleToAttribute or internal itself.
A better way would be to make sure you don't actually pass anonymous types over assembly boundaries - after all, they shouldn't even be used outside of the method they originated from; the fact that they are is basically an implementation detail of .NET - they didn't have another way to do the same thing. This could change in future versions, making the InternalsVisibleToAttribute solution doubly unreliable.
The way your code is using dynamic suggests that your team has flawed assumptions about how dynamic works and how it's supposed to be used. Note how the actual runtime type of List<dynamic> is actually List<object>. The same goes for arguments of type dynamic (which are again just object, albeit marked with DynamicAttribute). And in fact, that really is what dynamic is - it's a way to handle runtime dynamic dispatch - it's not a property of the type or anything, it's just the way you actually invoke whatever you're trying to invoke. For C#, dynamic allows you to skip most of the compiler checks when working with those dynamic types, and it generates some code to handle the dispatch for you automatically, but all of that only happens inside the method where you actually use the dynamic keyword - if you used List<object>, the end result would be exactly the same.
In your code, there's no reason not to use simple static types. Dynamic typing doesn't really give you any benefits, apart from the effort to code the types themselves. If your co-workers don't like that, well, they should present a better solution - the problem is quite obvious, and it's something you need to deal with.
Much worse, it explicitly hides all context, all the type information. That's not something you want in an API, internal or not! If you want to hide the concrete types being used, why not - but you should still expose an interface instead. I suspect this is the reason why anonymous types can't implement interfaces - it would encourage you to go entirely the wrong way.

Regarding generic Where T

void LoadParameters<T, TValue>(TValue strategy)
where T : Parameters
Saw a code like this. Will the program still work correctly without the where statement?
If it compiles without the where statement, it will work correctly. However, chances are the coder did not simply put it there without reason. If you remove it, it will likely not compile and hence not work.
That where clause is called a "generic type constraint". Usually T can be any type and you must write your generic code with that in mind. By constraining T to be, inherit or implement a specific type, you gain the ability to refer to the members of that type in your generic code, because the compiler is assured that any object used will be that type. You can also use class, struct or new as generic type constraints, which enforce T being a reference type, a value type or having a parameterless constructor respectively.

Declaring a LIST variable of an anonymous type in C#

I'm working with LINQ to SQL with ASP.NET 4 and C#. I've created a LINQ query that results in a new LIST (ie. ToList()). The returned LIST is of an ANONYMOUS type, because it's being created dynamically by the query. I want to be able to declare a variable at the page level in the code behind so I can use it in other functions and also on the front page using '<%= %>'.
Visual Studio tells me that the result is of an anonymous type, but gives me the classes names, for example: {CLASS1, CLASS2}.
How can I declare the variable of this anonymous type?
Anonymous types, by their very nature, can't be explicitly "declared". They're anonymous, unknown; you don't have a type to declare. As such, anonymous types, whether directly or as a generic type parameter, cannot be specified as parameters, used as a return type, or stored to any explicitly typed variable. You must use var to assign them, and that means you're pretty much limited to using the type in local scope.
Your only option, basically, is to convert your anonymous type into a collected type that can be explicitly declared (i.e. you must declare the type itself). Just create a simple DTO class, and before calling ToList, run the anonymous type through a Select() Linq node that uses the anonymous type to initialize your strong class.
If you are using .NET 4.0, you COULD go dynamic. The dynamic keyword, and any object that's been passed through a parameter or return type declared dynamic, basically tells the compiler not to try to verify any operation performed on it; you can try to use any operator, call any method, etc. HOWEVER, if the operator, member, or whatever other operation you are performing isn't valid for what the object actually is behind the scenes, you'll get runtime exceptions which you must handle very robustly. For this reason, the dynamic feature of .NET 4.0 is not to be used lightly.
The only other thing you can do, as Kratz said, is return an ArrayList, or an Object[] array, and use reflection to discover the anonymous type's structure. It's a no-no pretty much any way you slice it; you lose the strong typing of the collection, your code bloats considerably as you need several lines of code to perform even the simplest get or set operations, and reflection, again by its nature, can be up to 100x slower than the equivalent operation on a known static type.
You'll have to declare a type for the result, since there is no way I know of to outright declare an instance of an anonymous type. Even if you store it in a value, you would not be able to use it outside the scope where it was created.
You possible could use reflection to get at the values and just declare the variable as type IList, but that would be much more work than just creating a new type.
You could do a List<Object> and in your code you can test the type like :
if(myList[index].GetType() == typeof(Class1))
{
//put your code for class1
}
else if(myList[index].GetType() == typeof(Class2))
{
//put your code for class2
}

Anonymous Types

I have a Dictionary(TKey, TValue) like
Dictionary<int, ArrayList> Deduction_Employees =
new Dictionary<int, ArrayList>();
and later I add to that array list an anonymous type like this
var day_and_type = new {
TheDay = myDay,
EntranceOrExit = isEntranceDelay
};
Deduction_Employees[Employee_ID].Add(day_and_type);
Now how can I unbox that var and access those properties ??
First, you aren't unboxing the type. Anonymous types are reference types, not structures.
Even though you can technically create instances of the same type outside of the method they were declared in (as per section 7.5.10.6 of the C# 3.0 Language Specification, which states:
Within the same program, two anonymous
object initializers that specify a
sequence of properties of the same
names and compile-time types in the
same order will produce instances of
the same anonymous type.
) you have no way of getting the name of the type, which you need in order to perform the cast from Object back to the type you created. You would have to resort to a cast-by-example solution which is inherently flawed.
Cast-by-example is flawed because from a design standpoint, every single place you want to access the type outside the function it is declared (and still inside the same module), you have to effectively declare the type all over again.
It's a duplication of effort that leads to sloppy design and implementation.
If you are using .NET 4.0, then you could place the object instance in a dynamic variable. However, the major drawback is the lack of compile-time verification of member access. You could easily misspell the name of the member, and then you have a run-time error instead of a compile-time error.
Ultimately, if you find the need to use an anonymous type outside the method it is declared in, then the only good solution is to create a concrete type and substitute the anonymous type for the concrete type.
There are several ways.
Since the comments seems to indicate that I suggest you do this, let me make it clear: You should be creating a named type for your object since you intend to pass it around.
First, you can use Reflection, which another answer here has already pointed out.
Another way, which tricks .NET into giving you the right type is known as "cast by example", and it goes something like this: You need to pass your object through a generic method call, which will return the object as the right type, by inferring the right type to return.
For instance, try this:
private static T CastByExample<T>(T example, object value)
{
return (T)value;
}
and to use it:
var x = CastByExample(new { TheDay = ??, EntranceOrExit = ?? }, obj);
for the two ?? spots, you just need to pass something fitting the data type for those properties, the values will not be used.
This exploits the fact that multiple anonymous types containing the exact same properties, of the same type, in the same order, in the same assembly, will map to the same single type.
However, by this time you should be creating a named type instead.
An anonymous type has method scope. To pass an anonymous type, or a collection that contains anonymous types, outside a method boundary, you must first cast the type to object. However, this defeats the strong typing of the anonymous type. If you must store your query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.
Source: http://msdn.microsoft.com/en-us/library/bb397696.aspx
No you can't. You can only access the properties by using reflection. The compiler has no way of knowing what the type was, and since it's an anonymous type, you can't cast it either.
If you are using .NET 1.x - 3.x, you must use reflection.
If you use .NET 4.0, you could use a dynamic type and call the expected properties.
In neither case do you need to unbox; that's for value types. Anonymous types are always reference types.

Why should anonymous types cannot be passed around methods?

What is the design decision to lean towards not returning an anonymous types from a method?
You can return an instance of an anonymous type from a method - but because you can't name it, you can't declare exactly what the method will return, so you'd have to declare that it returns just object. That means the caller won't have statically typed access to the properties etc - although they could still pass the instance around, access it via reflection (or dynamic typing in C# 4).
Personally I would quite like a future version of C# to allow you to write a very brief class declaration which generates the same code (immutable properties, constructor, Equals/GetHashcode/ToString) with a name...
There is one grotty hack to go round it, called casting by example. I wouldn't recommend it though.
Because an anonymous type has no name. Therefore you cannot declare a return type for a method.
Because C# is statically typed language and in a statically typed language the return type of a method needs to be known at compile time and anonymous types have no names.
How can you use your type inside your method if the definition is only in the call of the method ?
It's not javascript.
A lot of answers heere seem to indicatie that it is not possible because of the current syntax and rule. But the question is about changing them. I think it would be possible, but a little complicated and resulting in an awkward (error-prone) syntax. Like
var f() { return new { A = "*", B = 1 }; }
var x = f();
The question is whether this adds sufficient value to the language to make it worth it.
At least up to 3.5, anonymous types are actually resolved at compile time, and this would be impossible (or quite hard) to do with anonymous method signatures.

Categories

Resources