Access <AnonymousType> fields - c#

I have an AnonymousType object that contacts two fields with their values. How can I access the value of these fields?
Ex:
SourceTypeObject { Source_Type_Id = 1, Source_Type_Name = "bibliography" }
I need to do something like : SourceTypeObject.Source_Type_Id
Is that possible?
EDIT:
Here's what I get if I tried to access the property directly:

Yes, this is the exact purpose of anonymous types. The only thing that might prevent you from doing so is if you passed the anonymous type around as a parameter with type "object". This would hide information about the anonymous type, and it would look like just any old object then.
The only recourse if this is the case is to use reflection, which is slow and awkward. Anonymous types are a meant to be a very "local" phenomenon, and if you find yourself wanting to use them elsewhere in the program, it's worth the time to promote it to a real type.
EDIT: In response to the image you posted, assuming the array is declared locally just outside of view, try to replace the object SourceTypeObject with var SourceTypeObject. This allows it to infer the anonymous type instead of being told that it's an object.

Related

Why you cannot declare a field and property as having an anonymous type?

I ran into a problem while doing my job, which is porting software from flash AS3 to .NET/Mono. In AS3 code base I can find many Object declarations that are initialized like this:
private const MAPPING:Object =
{
ssdungf:'flydung',
ssdungt:'flydung',
superfutter:'superfeed'
}
The best option for me would be in C# using anonymous type like this:
var MAPPING = new
{
ssdungf = "flydung",
ssdungt = "flydung",
superfutter = "superfeed"
};
The problem is... well let me quote MSDN (source):
You cannot declare a field, a property, an event, or the return type of a method as having an anonymous type
But they don't say why.
So the question remains: why you cannot declare a field and property as having an anonymous type? Why .NET creators stripped it from that option?
I am getting warning here from SO that my question appears subjective, but I think it is not at all - there need to be objective reason for that.
As for me, I don't see any obstacles for that but somehow it is not supported. As compiler can easily generate the type for field or property of class, in a same manner as it does for local variables.
The option for me was to use dynamic type but unfortunately Mono engine I am using is stripped from that.
Also the option for me is to use object type and using later reflection to find these fields:
private static readonly object MAPPING = new
{
ssdungf = "flydung",
ssdungt = "flydung",
superfutter = "superfeed"
};
But using reflection is this situation is dirty I would say.
I tried to find answer, but I really didn't find any. Here are some SO answers to similar questions, but they don't answer why:
Can a class property/field be of anonymous type in C# 4.0?
Declaring a LIST variable of an anonymous type in C#
How do you declare a Func with an anonymous return type?
Why you cannot declare a field and property as having an anonymous type?
Because C# is statically typed, so any memory location has to be given a type, and declaration does so. With locals we can infer from context if its initialised at the same time as declaration with var but that is a shorthand for a type that is usable even when the type hasn't got a name.
What would a field with an anonymous type, that is to say a statically-bound but indescribable type, mean?
dynamic would indeed be the closest analogy to the code you are porting, but since that isn't available to you, you might consider using an IDictionary<string, object> (which incidentally is how ExpandoObject, which is often used with dynamic to have objects that behave more like javascrpt objects, works behind the scenes). This would be slower and less type-safe than if you created a class for the object needed, but can work.
The problem on an anoynmous property is: how do you get/set it?
Suppose it would work:
class MyClass
{
public MyField = new { TheValue = "Hello World" };
}
Now in your consuming code you´d write code to read the code:
MyClass m = new MyClass();
m.MyField.TheValue = "newValue";
How was this different from having a type for MyField? All you´d get is that you can omit two or three lines of code whilst gaining nothing. But I think you might produce many problems as no-one knows what he can assign to/expect from that member.
Furthermore you can´t do much with an anonymous object, basically you can just set it and read it. There are no methods (except Equalsand GetHashCode inherited from object) that you can call so the opportunities are quite low.
Last but not least an anonymous object is usually used as temporaryily, for example within a Select-statement. When you use it you say: this type is going to be used only within the current specific scope and can be ignored by the entire world as internal implementation-detail. Creating a property of an anonymous type will expose such a detail to the outside. Of course you could argue that the designers could at least allow them for private members, but I guess doing so would bypass the complete concept of accessability for nothing.

C# Apply Attribute to Dynamic object [duplicate]

I have a anonymous class:
var someAnonymousClass = new
{
SomeInt = 25,
SomeString = "Hello anonymous Classes!",
SomeDate = DateTime.Now
};
Is there anyway to attach Attributes to this class? Reflection, other? I was really hoping for something like this:
var someAnonymousClass = new
{
[MyAttribute()]
SomeInt = 25,
SomeString = "Hello anonymous Classes!",
SomeDate = DateTime.Now
};
You're actually creating what is called an anonymous type here, not a dynamic one.
Unfortunately no there is no way to achieve what you are trying to do. Anonymous types are meant to be a very simple immutable type consisting of name / value pairs.
The C# version of anonymous type only allows you to customize the set of name / value pairs on the underlying type. Nothing else. VB.Net allows slightly more customization in that the pairs can be mutable or immutable. Neither allow you to augment the type with attributes though.
If you want to add attributes you'll need to create a full type.
EDIT OP asked if the attributes could be added via reflection.
No this cannot be done. Reflection is a way of inspecting metadata not mutating it. Hence it cannot be used to add attributes.
Additionally, type definitions in an assembly, and in general, are immutable and cannot be mutated at runtime [1]. This includes the adding of attributes to a method. So other reflection like technologies cannot be used here either.
[1] The one exception to this is ENC operation
First of all, this is an anonymous type. The word "dynamic" might lead people to think you're talking about a C# 4.0 class implementing dynamic semantics, which you aren't.
Secondly, no, you're not able to do what you ask.
If you need to specify attributes for your properties, you're back to a named type, ie. a normal class or struct.
It is possible to add attributes to an anonymous instance using TypeDescriptor.AddAttributes. You can then later access the attributes using TypeDescriptor.GetAttributes.
This will not add them to the Type instance for the object. So it may not be useful in your case if you do not control the code that retrieves and applies the attributes.

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.

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.

Categories

Resources