c# get multidimensional array value - c#

How to get data from array sample code below
var AllData = new Dictionary<string, object>
{
{ "TestFun", await TestFun() },
};
var TestFun = AllData["TestFun"] // ok
ArrayList Humidity = (ArrayList)AllData["TestFun"]; // Error
String String1= TestFun["String1"] // ???
private static async Task<Dictionary<string, object>> TestFun() {
var MultiArray = new Dictionary<string, object>
{
{ "String1", "Value1"},
};
return MultiArray;
}
Error
System.InvalidCastException: 'Unable to cast object of type > 'System.Collections.Generic.Dictionary`2[System.String,System.Object]' to type > 'System.Collections.ArrayList'.'
Or
Cannot apply indexing with [] to an expression of type 'object'
Tried to get an answer here but couldn't find a solution...

TestFun() returns a Dictionary<string,object>.
System.InvalidCastException: 'Unable to cast object of type > 'System.Collections.Generic.Dictionary`2[System.String,System.Object]' to type > 'System.Collections.ArrayList'.'
The exception tells you that it is not possible to cast/convert it to an ArrayList. You are trying to go from apples to monkeys.
You can either replace the type of the MultiArray variable to be an ArrayList or change the cast type to Dictionary<string,object>

Dictionary<string, object> TestFun = (Dictionary<string, object>)AllData[key: "TestFun"];
string String1 = (string) TestFun["String1"];
Console.WriteLine(String1); // Value1

Related

output value types from If Else block using Dictionaries

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
}
}

Convert object {object[]} to string[]

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();
}
}

Error when use Dynamic Linq & ICompare

I read this topic and apply to my code.
//listSort contains ExpandoObjects
List<dynamic> listSort = new List<dynamic>(listDynamic.Count);
foreach (var item in listDynamic)
{
dynamic objDynamic = OrderBySpecialCharacter.ConvertToExpand(item);
string sortValue = OrderBySpecialCharacter.GetValueInExpandoObject(objDynamic, colSortText);// "Name");
objDynamic.Sort = OrderBySpecialCharacter.ConvertToACSII(sortValue.ToUpper());
listSort.Add(objDynamic);
}
List<dynamic> sortedList = new List<dynamic>();
if (colSort2 == null && colSort3 == null)
{
//Error in below line
sortedList = listSort.OrderBy(x=> x.GetReflectedPropertyValue("Sort"),new MrFourCompare<string>()).ToList();
}
----------------
public static ExpandoObject ConvertToExpand<T>(T objInput)
{
ExpandoObject objExpand = new ExpandoObject();
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
IDictionary<String, Object> iExpand = ((IDictionary<String, Object>)objExpand);
foreach (PropertyDescriptor prop in properties)
iExpand.Add(prop.Name, prop.GetValue(objInput));
return (ExpandoObject)iExpand;
}
--------------------
And I see error:
Severity Code Description Project File Line Suppression State
Error CS0411 The type arguments for method
'Enumerable.OrderBy(IEnumerable, Func, IComparer)' cannot be inferred from the usage. Try
specifying the type arguments
explicitly. DemoDynamicObject C:\Users\MrFour-IT\Desktop\DemoDynamicObject\DemoDynamicObject\OrderBySpecialCharacter.cs 154 Active
I don't know how to fix it! Please help me! Thanks
If your have IComparer like this code:
public class MrFourCompare: IComparer<String>
{
public int Compare(string x, string y)
{
return string.Compare(x, y);
}
}
according your referred link you most change this line:
sortedList = listSort.OrderBy(x=> x.GetReflectedPropertyValue("Sort"),new MrFourCompare<string>()).ToList();
to
sortedList = listSort.OrderBy(x=> x.GetReflectedPropertyValue("Sort"),new MrFourCompare()).ToList();
because in implementation of IComparer you set it up to string.
Edit:
IComparer can not be Dynamic, so if you want to sort by Sort property of dynamic value you most cast sort property to exact type like String or Int.
sortedList = listSort.OrderBy(x=> (string)x.GetReflectedPropertyValue("Sort"),new MrFourCompare()).ToList();

I get an error while trying to assign Dictionary<string, object> to a string variable

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]);

Convert Hashtable elements to List

I have this
hashtable has a
key "ids" and its values are [1,2,3]
List<long> ids= (List<long>)hashtable["ids"];
an error occurs when trying to cast. It says
Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'System.Collections.Generic.List`1[System.Int64]'.
I've been stuck for hours, any suggestions?
It would be helpful if you wrote in your question what are the values you expect to get and the definition of your hashtable.
Assuming You are trying to get [1,2,3] and your 'Value' is an array of long, try:
List<long> ids= hashtable["ids"].ToList();
public static List<dynamic> ToDynamicList(this Hashtable ht)
{
var result = new List<dynamic>();
foreach (DictionaryEntry de in ht)
{
result.Add(new { key = de.Key, value = de.Value });
}
return result;
}

Categories