Search code examples
c#arraysienumerableenumerable

Accessing elements of an Array (of any element type) from an object


I use management to access devices properties and I wrote a code below to create an array of dictionaries. my application show properties in a listview control; so I need to convert all properties value to simple string

Dictionary<string,string>[] getInfo(string k) {
    // using `k` as management-key
    var mos = new ManagementObjectSearcher($"select * from {k}");
    var devices = new List<Dictionary<string, string>>();
    var mosc = mos.Get();    // mosc is a collection of all devices with same key
    foreach (var device in mosc) {
        var properties = new Dictionary<string, string>();
            foreach (var p in device.Properties) {
                if (p.Value != null) {
                    if (p.IsArray) {
                        // I have problem in here
                        // my application must convert p.value to string
                        var collection = (IEnumerable<object>)p.Value
                        properties[p.Name] = string.Join(", ", collection.Select(x=>x.ToString()));
                    } else
                        properties[p.Name] = p.Value.ToString();
                } else properties[p.Name] = "";
            }
        devices.Add(properties);
        }
    return devices.ToArray();
}

p.Value type is object but sometimes it contain an array like UInt[] or String[], I found part of code from stackoverflow but it didn't help me and it say:

System.InvalidCastException: 'Unable to cast object of type 'System.UInt16[]' to type 'System.Collections.Generic.IEnumerable`1[System.Object]'.'

I tried code below too, but it say same thing:

int[] array = new int[] { 0, 1, 2 }; // <- I haven't access to `array` in my main problem
object obj=array;
// I only can use `obj`
// `obj` is similar to `p.Value` here
IEnumerable<object> collection = (IEnumerable<object>)obj;   // <- this line throws exception!
string output=string.join(", ",collection.Select(x=>x.ToString()));

I also tried this codes:

var collection= p.Value as IEnumerable;
// ^ found this line from stackoverflow
// says: Using the generic type 'IEnumerable<T>' requires 1 type arguments

var collection= p.Value as IEnumerable<object>
// `collection` will be null

var collection= (object[]) p.Value
// says: Unable to cast object of type 'System.Int32[]' (or some something like String[]) to type 'System.Object[]'.

Solution

  • second code:

    int[] array = new int[] { 0, 1, 2 };
    object obj=array;
    var obj_array=(Array)obj;
    IEnumerable<object> collection = obj_array.Cast<object>();
    string output=string.join(", ",collection.Select(x=>x.ToString()));
    

    so main code will be:

    Dictionary<string,string>[] getInfo(string k) {
        // using `k` as management-key
        var mos = new ManagementObjectSearcher($"select * from {k}");
        var devices = new List<Dictionary<string, string>>();
        var mosc = mos.Get();    // mosc is a collection of all devices with same key
        foreach (var device in mosc) {
            var properties = new Dictionary<string, string>();
                foreach (var p in device.Properties) {
                    if (p.Value != null) {
                        if (p.IsArray) {
                            var array = (Array)p.Value;
                            var collection = array.Cast<object>();
                            properties[p.Name] = string.Join(", ", collection.Select(x=>x.ToString()));
                        } else
                            properties[p.Name] = p.Value.ToString();
                    } else properties[p.Name] = "";
                }
            devices.Add(properties);
            }
        return devices.ToArray();
    }