簡體   English   中英

從 object 訪問數組的元素(任何元素類型)

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

我使用管理來訪問設備屬性,並在下面編寫了一個代碼來創建一個字典數組。 我的應用程序在listview控件中顯示屬性; 所以我需要將所有屬性值轉換為簡單的字符串

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類型是object但有時它包含像UInt[]String[]這樣的數組,我從stackoverflow找到了部分代碼,但它沒有幫助我,它說:

System.InvalidCastException:'無法將'System.UInt16[]'類型的 object 轉換為'System.Collections.Generic.IEnumerable`1[System.Object]'。

我也嘗試了下面的代碼,但它說的是同樣的事情:

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

我也試過這個代碼:

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[]'.

IEnumerable<T>T中是協變的,因此這是允許的:

IEnumerable<Giraffes> giraffes = ....
var animals = (IEnumerable<Animal>)giraffes;

那么,為什么這不起作用呢?

var array = new[] { 1, 2, 3 };
var objects = (IEnumerable<object>)array; //will not compile

int擴展object ,對嗎?

好吧,原因是 C# 中的類型差異只允許在引用類型之間; 規則是方差必須優先於身份,並且沒有辦法在 C# 中強制轉換值類型保留身份; 只有引用類型可以並且這些類型的轉換稱為引用轉換

var animal = (Animal)giraffe;
var o = (object)"Hello";
IFish fish = cod;
//etc.

組成 object 的位不會改變,只是引用的類型改變,因此轉換的名稱。 請注意,在第一個示例中, animalsgiraffes是相同的 object、 object.ReferenceEquals(animals, giraffes)將返回true 我們只改變了引用它的變量的類型。

在您的情況下,要從IEnumerable<someValueType>獲取IEnumerable<object> ,您必須枚舉並裝箱每個項目,以創建所需類型的新枚舉 為此,您可以使用擴展方法Enumerable.Cast<T>()

IEnumerable<object> objects = array.Cast<object>();

或者自己做投影:

IEnumerable<object> objects = array.Select(i => (object)i);

第二個代碼:

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

所以主要代碼將是:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM