I have received data of type object {System.Collections.Generic.Dictionary<string, object>}. Parsing this is pretty straightforward:
Dictionary<string, object> parsedData = data as Dictionary<string, object>;
Now I am trying to access parsedData["stringArr"] of type object {object[]}. I got stuck when trying to convert this object {object[]} to string[].
I can't even iterate this:
foreach (object o in parsedData["stringArr"]){}
//returns Exception("...'object' does not contain a public instance definition for GetEnumerator")
One way you could get the object values as string[] is to use the as cast, just like you did with the original data:
object data = new Dictionary<string, object>
{
{"stringArr", new[] {"item1", "item2", "item3"}},
};
var parsedData = data as Dictionary<string, object>;
// cast the object values to string[]
foreach (var o in parsedData["stringArr"] as string[])
{
Console.WriteLine(o);
}
// Output:
// item1
// item2
// item3
That's because parsedData["stringArr"] is an object, not a object[].
I think you want to change the dictionary type parameters:
Dictionary<string, object[]> parsedData = data as Dictionary<string, object[]>;
If you have a Dictionary<string, object>, and you know a particular key's value has a more specific type, cast it as that type:
foreach (string s in (string[])parsedData["stringArr"])
You will of course receive exceptions if the value at that key is not of that type. A "safer" way of doing it would be to check first:
if (parsedData["stringArr"] as string[] data != null)
{
foreach (string s in data)
{
...
}
}
First of all, thank you all for your energy to help me to solve it. I would just bash my keyboard for a few more hours without you. I can't understand why extra conversion to object[] is required yet, but what works is:
Dictionary<string, object> parsedData = data as Dictionary<string, object>;
if (parsedData.ContainsKey("stringArr"))
{
foreach (object o in parsedData["stringArr"] as object[])
{
string myString = o.ToString();
}
}
Related
I am trying to add value to an outer variable val_dict from if and else block in the for loop. The problem is that the output type from if block is different from the output type of else block which throws a type error for either of them if i initialize the variable to one of the output type classes.
In short the val_dict is an object that can either be a dictionary<string,object> or a null object, but some how i cannot seem to define a common type for both of these object types.
here is the code:
Dictionary<string, Dictionary<string,object>> data_dict =
new Dictionary<string, Dictionary<string, object>>();
foreach (KeyValuePair<(string, string), object> cat_nam_val in dataset)
{
var val_dict = new Dictionary<string, object>(); //use val_dict as dictionary or object
if (target_survey_id != null)
{
data_dict[target_survey_id].TryGetValue(cat_nam_val.Key.Item1, out val_dict);
}
else
{
data_dict.TryGetValue(cat_nam_val.Key.Item1, out val_dict);
}
if (IsDictionary(val_dict));
{
val_dict[cat_nam_val.Key.Item2] = cat_nam_val.Value; //generate new dict becoz val_dict is an object so cannot be indexed
}
}
You cannot coerce types when using out. As a result, you can use a temporary out variable and then cast it if you are certain that it is a dictionary.
foreach (KeyValuePair<(string, string), object> cat_nam_val in dataset)
{
var val_dict = new Dictionary<string, object>(); //use val_dict as dictionary or object
if (target_survey_id != null)
{
// use a temporary variable to work around type mismatch
data_dict[target_survey_id].TryGetValue(cat_nam_val.Key.Item1, out var temp_val_dict);
// if you know that object is a dictionary, cast and assign
val_dict = (Dictionary<string, object>)temp_val_dict;
}
else
{
data_dict.TryGetValue(cat_nam_val.Key.Item1, out val_dict);
}
if (IsDictionary(val_dict))
{
val_dict[cat_nam_val.Key.Item2] = cat_nam_val.Value; //generate new dict becoz val_dict is an object so cannot be indexed
}
}
Dictionary<string, object> myVal = new Dictionary<string, object>();
myVal.Add("key1", "value1");
myVal.Add("key2", "value2");
foreach (var val in myVal)
{
if (val.Key == "key1")
{
string mystr = val.Value;
Console.Write(val.Value);
Console.ReadLine();
}
}
I am getting this error:
Cannot implicitly convert type 'object' to 'string'. An explicit
conversion exists (are you missing a cast?)
Why you are getting such Error:
While iterating the Collection(Dictionary<string, object>) using foreach (var val in myVal) each val will be a KeyValuePair<string, object> where val.Key denotes the Key and val.Value denotes the Value corresponding to the key.
In your case the value will be of type object since your collection is of type <string, object>. And by using string mystr = val.Value; you are assigning an object to a string variable. as per rules this assignment is not permitted.
Solution:
Cast the object to a string like the following:
string mystr = (string)(val.Value);
The statement myVal.Add("key2", "value2"); that populates the Dictionary indicates that both the key and value are of string type so you can re-define the Dictionary as
Dictionary<string, string> myVal = new Dictionary<string, string>();
Two choices:
Either use a Dictionary<string, string>
or
Cast the object instances you get out of the Dictionary<string, object> to a string
string mystr = (string)(val.Value);
my bad, I found that there are nested dictionaries and inside which another List operates that caused the issue. I just added some foreach loop to reach into the final dictionary and dig into the List which worked perfectly.
My last piece looks as below:
Messages.Add(Path.GetFileName(fileName), ((List<string>)(runResult.Single(m => m.Key == "Messages")).Value)[0]);
I have the method
HandleNotification(string message, Dictionary<string, object> additionalData, bool isActive)
and I would take the from additionalData the value.
I have this additional data:
Extracoins:4
I don't understand how I can take the value 4 from additionalData for a specific key Extracoins.
You can get a value from a Dictionary like this if your only interested in accessing one specific key.
object value = null;
additionalData.TryGetValue("Extracoins", out value);
That way object will be the value in the Dictionary or it will remain null if the value is not found.
Or you can do:
if (additionalData.ContainsKey("Extracoins"))
{
object value = additionalData["Extracoins"];
}
Finally if you wanted to iterate over all the values in the Dictionary until you get the correct value you could do:
object value = null;
foreach (KeyValuePair<string, object> pair in additionalData)
{
if (pair.Key == "Extracoins")
{
value = pair.Value;
}
}
I have a dynamic object that looks like this,
{
"2" : "foo",
"5" : "bar",
"8" : "foobar"
}
How can I convert this to a dictionary?
You can fill the dictionary using reflection:
public Dictionary<String, Object> Dyn2Dict(dynamic dynObj)
{
var dictionary = new Dictionary<string, object>();
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dynObj))
{
object obj = propertyDescriptor.GetValue(dynObj);
dictionary.Add(propertyDescriptor.Name, obj);
}
return dictionary;
}
You can use a RouteValueDictionary to convert a C# object to a dictionary. See: RouteValueDictionary Class - MSDN. It converts object properties to key-value pairs.
Use it like this:
var toBeConverted = new {
foo = 2,
bar = 5,
foobar = 8
};
var result = new RouteValueDictionary(toBeConverted);
If the dynamic value in question was created via deserialization from Json.Net as you mentioned in your comments, then it should be a JObject. It turns out that JObject already implements IDictionary<string, JToken>, so you can use it as a dictionary without any conversion, as shown below:
string json =
#"{ ""blah"" : { ""2"" : ""foo"", ""5"" : ""bar"", ""8"" : ""foobar"" } }";
var dict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
dynamic dyn = dict["blah"];
Console.WriteLine(dyn.GetType().FullName); // Newtonsoft.Json.Linq.JObject
Console.WriteLine(dyn["2"].ToString()); // foo
If you would rather have a Dictionary<string, string> instead, you can convert it like this:
Dictionary<string, string> newDict =
((IEnumerable<KeyValuePair<string, JToken>>)dyn)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString());
You can use Json.Net to deserialize it to dictionary.
string json = dynamicObject.ToString(); // suppose `dynamicObject` is your input
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Very similar to ema answer, but with a one-liner using LINQ magic:
Dictionary<string, object> myDict = sourceObject.GetType().GetProperties().ToDictionary(prop => prop.Name, prop => prop.GetValue(sourceObject, null));
Another way is using System.Web.Helpers.Json included in .NET 4.5.
Json.Encode(object) and Json.Decode. Like:
Json.Decode<Generic.Dictionary<string, string>>(value);
MSDN: https://msdn.microsoft.com/en-us/library/gg547931(v=vs.111).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
Regards,
MarianoC.
You can do it with jsonSerializer. And it requires System.Net.Extensions reference. Here is a sample code.
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string,string>>(jsonText);
var place = dict["8"]; // "foobar"
If you use the dynamic implementation here:
https://github.com/b9chris/GracefulDynamicDictionary
You can get the Dictionary right from the implementation. One advantage to using the above implementation (written for an answer to another SO question), is you can shift easily between the specific implementation and dynamic, like so:
dynamic headers = new DDict();
headers.Authorization = token;
if (doesNeedSiteId)
headers.SiteId = siteId;
await post(headers);
}
protected async Task post(DDict headers)
{
var dict = headers.GetDictionary(); // Dictionary<string, object>
In the above, the headers collection is conveniently created as a dynamic, but, the underlying specific implementation is DDict, and the post() method accepts it even though you've declared it as dynamic and used its features.
I use a 3rd party library and am un able to get the object arrays' content
IDictionary dic=SomeFunc(); // this function returns an IDictionary
and I use DictionaryEntry to get its content
foreach(DictionaryEntry de in dic)
{
//each of de.Value is implemented as a KeyValuePair<object,object>
//I have not yet learned how to read each de.Value's key and value pair
}
Could you offer me a hint to get the strings inside de.Value which is a dictionary of object to object ?
EDIT
Each value of de.Values is a key value pair of type "object" to "object". It reports error when I cast it to string
foreach (DictionaryEntry de in dic)
{
foreach(KeyValuePair<string,string> k in (Dictionary<string,string>)de.Values)
{
//error: instance is null
}
}
make use of is keywork
if(de.value is typeof(Dictionary))
//than do code
not sure but this will work
To access only the values, have this:
foreach (object value in dic.Values)
{
MessageBox.Show(value.ToString());
}
If you mean each value is Dictionary by its own right then you can have nested loop:
foreach (object value in dic.Values)
{
Dictionary<object, object> nestedDic = (Dictionary<object, object>)value;
foreach (object nestedValue in nestedDic.Values)
{
MessageBox.Show(nestedValue.ToString());
}
}