I have a function that returns an anonymous type like so (simplified for illustrative purposes)...
public object GetPropertyInfo()
{
return new {
PropertyName = "Foo",
Value = "Laa"
};
}
When I do this...
dynamic pi = GetPropertyInfo();
Console.WriteLine(pi);
It outputs this (the same as if I did '?pi' in the immediate window)...
{ PropertyName = "A", Value = 44 }
PropertyName: "A"
Value: 44
But if I try doing this...
string propertyName = pi.PropertyName;
...it compiles but throws a runtime exception saying
Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in System.Core.dll
Additional information: 'object' does not contain a definition for 'PropertyName'
What gives? What am I missing here?
The compiler generates a name for each anonymous type. If two or more anonymous type objects are defined in the same assembly and the sequence of properties are same in terms of names and types than the compiler treats both as same object instances of type.
Way 2: Handle by creating same anonymous type object o = AnonymousReturn(); var obj = Cast(o, new { Name = "", EmailID = "" }); Console. WriteLine(obj.Name + " " + obj. EmailID); In this way return value of the anonymous type is get assigned to object.
An anonymous type is a temporary data type that is inferred based on the data that we include in an object initializer. Properties of anonymous types are read-only in nature so cannot change their values. Let us try to change the value of Age.
The problem is that anonymous types are internal, which means that you can't access their properties with dynamic
property accessors from projects other than the one they were created in. The dynamic binding treats them as the closest public inherited type it knows about--object
.
To fix this, you can declare a public type to represent the values you're expecting to find in your anonymous type. This is probably a good idea anyway, since you're clearly expecting to consume the returned properties in other parts of your code. Using a declared type also enables you to maintain type-safety, avoiding the need for dynamic
entirely.
If you absolutely must use dynamic
s here, the next best option is probably to change your AssemblyInfo.cs
file to make internal properties accessible to the project you're trying to access them from:
[assembly:InternalsVisibleTo("MyOtherProject")]
Edit
According to your edit. Apparently you are not required dynamic at all as there are no dynamic properties. Just create a concrete type with your predefined properties. It's better to avoid dynamic when possible anyway.
Old Answer
You need to use an ExpandoObject
. Reference here.
In fact, GetPropertyInfo()
should return an ExpandoObject
.
dynamic foo = this.GetPropertyInfo();
string i = foo.MyPropertyName;
private ExpandoObject GetPropertyInfo()
{
dynamic obj = new ExpandoObject();
obj.PropertyName = "MyPropertyName";
obj.PropertyType = "MyPropertyType";
return obj;
}
The ExpandoObject class enables you to add and delete members of its instances at run time and also to set and get values of these members. This class supports dynamic binding, which enables you to use standard syntax like sampleObject.sampleMember instead of more complex syntax like sampleObject.GetAttribute("sampleMember").
Also, you can use System.Reflection
object D = GetPropertyInfo();
Type t = D.GetType(); // get object's type
PropertyInfo p = t.GetProperty("PropertyName"); // look up for the property:
object P = p.GetValue(D, null); // get the value
Fiddle demo
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