Dynamically adding properties to a dynamic object? - c#

i have this
dynamic d = new ExpandoObject();
d.Name = attribute.QualifiedName.Name;
so , i know that d will have a property Name. Now if i don't know the name of the property at compile time , how do i add that property to the dynamic.
i found this SO Question
so, there is this complicated concept of call binders etc..which is tough to get in the first place.any simpler way of doing this ?

dynamic d = new ExpandoObject();
((IDictionary<string,object>)d)["test"] = 1;
//now you have d.test = 1

Here is a cleaner way
var myObject = new ExpandoObject() as IDictionary<string, Object>;
myObject.Add("Country", "Ireland");

You can also do like this:-
Dictionary<string,object> coll = new Dictionary<string,object>();
coll.Add("Prop1","hello");
coll.Add("Prop2",1);
System.Dynamic.ExpandoObject obj = dic.Expando();
//You can have this ext method to better help
public static ExpandoObject Expando(this IEnumerable<KeyValuePair<string, object>>
dictionary)
{
var expando = new ExpandoObject();
var expandoDic = (IDictionary<string, object>)expando;
foreach (var item in dictionary)
{
expandoDic.Add(item);
}
return expando;
}

Related

C# Equilavent of "dynamic" JavaScript object?

I want to create a single object (possibly Dictionary) with string keys that will have different variable types as the value (string, int, bool, Dictionary<string,string> etc). Is this possible?
*I understand this might just be a fundamental difference of two languages AKA square peg round hole
You can use dynamic as values type, that match better than object to the question and you need no future castings:
var dictionary = new Dictionary<string, dynamic>();
dictionary.Add("1", 10);
dictionary.Add("2", "test");
dictionary.Add("3", true);
foreach ( var item in dictionary )
Console.WriteLine($"{item.Key} is type: {item.Value.GetType().Name} = {item.Value}");
Console.WriteLine();
int v = dictionary["1"] + 10;
Console.WriteLine(v);
string s = dictionary["2"] + " one";
Console.WriteLine(s);
bool b = !dictionary["3"];
Console.WriteLine(b);
Output
1 is type: Int32 = 10
2 is type: String = test
3 is type: Boolean = True
20
test one
False
https://learn.microsoft.com/dotnet/csharp/programming-guide/types/using-type-dynamic
A Dictionary<string, object> is roughly equivalent to an object in JavaScript.
Example:
var dictionary = new Dictionary<string, object>
{
"myString" = "helloWorld",
"myChild" = new Dictionary<string, object>
{
"myName" = "bobby tables"
}
};
var myString = (string)dictionary["myString"];
var myName = (string)((Dictionary<string, object>)dictionary["myChild"])["myName"];
You can also use the dynamic keyword and ExpandoObject.
dynamic obj = new ExpandoObject();
obj.MyString = "helloWorld";
obj.MyChild = new ExpandoObject();
obj.MyChild.MyName = "bobby tables";
string myString = obj.MyString;
string myName = obj.MyChild.MyName;

dynamic Objects with variables in c#

Is it possible to build dynamic objects having the property name set to the value of a variable?
for instance this seems standard...
dynamic elem = new Object();
elem.Name = "myName";
but how would this be implemented?...
string fn = "FirstName";
string ln = "LastName";
dynamic elem = new Object();
elem.fn = "John";
elem.ln = "Doe";
where as i would be able to call the properties like...
string fn = elem.FirstName;
The ExpandoObject also implements IDictionary<string, object>, meaning you can add properties using a string key.
dynamic person = new ExpandoObject();
person.FirstName = "Alex";
var ln = "lastname";
(person as IDictionary<string, Object>)[ln] = "KeySmith";

Create c# dynamic object from elements of a list

how to convert :
A List :
var list = new List<string>(){"str1","str2"}
to a anonymous object :
var anonymousObject = new {str1 = "str1",str2 = "str2"}
during runtime
You can use the ExpandoObject which will give you the feature of dynamic type.
var list = new List<string>() { "str1", "str2" };
ExpandoObject obj = new ExpandoObject();
var store = (IDictionary<string, object>)obj;
list.ForEach(x => store.Add(x, x));
dynamic lst = obj;
var val = lst.str1; // Test
You can also use extension method represented below (from here).
Because converting list to dynamic object by iterating on items manually can be painful when there is many situations like this in your application.
You can use this extension method like this:
dynamic list = new List<string>() { "str1", "str2" }
.ToDictionary(dd => dd, dd => (object)dd)
.ToExpando();
The extension method:
public static ExpandoObject ToExpando(this IDictionary<string, object> dictionary)
{
var expando = new ExpandoObject();
var expandoDic = (IDictionary<string, object>)expando;
// go through the items in the dictionary and copy over the key value pairs)
foreach (var kvp in dictionary)
{
// if the value can also be turned into an ExpandoObject, then do it!
if (kvp.Value is IDictionary<string, object>)
{
var expandoValue = ((IDictionary<string, object>)kvp.Value).ToExpando();
expandoDic.Add(kvp.Key, expandoValue);
}
else if (kvp.Value is ICollection)
{
// iterate through the collection and convert any strin-object dictionaries
// along the way into expando objects
var itemList = new List<object>();
foreach (var item in (ICollection)kvp.Value)
{
if (item is IDictionary<string, object>)
{
var expandoItem = ((IDictionary<string, object>)item).ToExpando();
itemList.Add(expandoItem);
}
else
{
itemList.Add(item);
}
}
expandoDic.Add(kvp.Key, itemList);
}
else
{
expandoDic.Add(kvp);
}
}
return expando;
}

adding new properties in expando object in foreach loop

I have to add new properties in expando object in foreach loop but I am not able to see a way to do it. Here is the example:
var allProperties = new List { "Name", "Email", "Roles" };
allProperties.AddRange(metaDataModel.GetFormattedFolders());
dynamic expando = new ExpandoObject();
foreach (var s in allProperties)
{
expando.s = string.Empty;
}
It consider 's' as a property instead of considering value of 's' as property name.
Thanks
var expando = new ExpandoObject() as IDictionary<string, Object>;
foreach (var s in allProperties)
{
expando.Add(s, string.Empty);
}

Dynamic object property name begins with number

I have a dynamic object whose property begins with number. How to access this property?
For inst:
myResult.123; // this is unvalid
Any helps would be very appreciated.
If you are using ExpandoObject for your dynamic object, you can cast to IDictionary<string, object> and use an indexer;
dynamic expando = new ExpandoObject();
var dict = (IDictonary<string, object>)expando;
dict["123"] = 2;
Many other dynamic object implementations (e. g. JObject in Json.NET) provide similar functionality.
Here's an example with JObject:
var json = JsonConvert.SerializeObject(new Dictionary<string, object> { { "123", 10 } });
var deserialized = JsonConvert.DeserializeObject<object>(json);
// using the IDictionary interface
var ten = ((IDictionary<string, JToken>)deserialized)["123"].Value<JValue>().Value;
Console.WriteLine(ten.GetType() + " " + ten); // System.Int64 10
// using dynamic
dynamic d = deserialized;
Console.WriteLine(d["123"].Value.GetType() + " " + d["123"].Value); // System.Int64 10
Modified
Type t = myResult.GetType();
PropertyInfo[] props = t.GetProperties();
Dictionary<string, object> dict = new Dictionary<string, object>();
foreach (PropertyInfo prp in props)
{
object value = GetPropValue(myResult, prp.Name);
dict.Add(prp.Name, value);
}
public static object GetPropValue(object src, string propName)
{
return src.GetType().GetProperty(propName).GetValue(src, null);
}

Categories