簡體   English   中英

如何將未知類型的 IList(類型在運行時已知)轉換為數組?

[英]How to convert IList of unknown type (type is known at runtime) to array?

我正在使用反射在運行時復制任何自定義 class 的 object。 我正在使用FieldInfo獲取所有字段,然后根據它們的類型正確復制它們。

只有在復制算法開始時我可以使用的類型是System.Object (AKA object )。 我做了很多類型檢查。 因此,當我的檢查方法說這個特定的 object 是一些簡單的一維數組時,毫無疑問,它是數組。 但是,我只能在運行時訪問該數組中的元素類型。

我確實像這樣成功復制了List<type known at runtime>

public object Get_ListCopy(object original)
{
    Type elementType = original.GetType().GetGenericArguments()[0];
    Type listType = typeof(List<>).MakeGenericType(elementType);

    object copy = Activator.CreateInstance(listType);
    var copyIList = copy as IList;

    foreach (var item in original as IEnumerable)
        copyIList.Add(item);

    copy = copyIList;

    return copy;
}

然后我嘗試重新編寫簡單數組的方法:

public object Get_ArrayCopy(object original)
{
    Type elementType = original.GetType().GetElementType();    // difference here
    Type listType = typeof(List<>).MakeGenericType(elementType);

    object copy = Activator.CreateInstance(listType);
    var copyIList = copy as IList;

    foreach (var item in original as IEnumerable)
        copyIList.Add(item);

    copy = Enumerable.Range(0, copyIList.Count).Select(i => copyIList[i]).ToArray();    // difference here

    return copy;
}

但是,當使用FieldInfo.SetValue(copyObject, convertedValue) // where convertedValue is object copy from the method above

System.ArgumentException: 'Object of type 'System.Object[]' cannot be converted to type 'System.Int32[]'.'

對於該特定示例,數組如下所示:

public int[] Array = { 1, 2, 3 };

最后一件事:我知道如何使用泛型方法和MethodInfo...MakeGenericMethod(...).Invoke來解決這個問題,我只是認為可以避免(也許我錯了)。 也不能使用序列化。

你的線

copy = Enumerable.Range(0, copyIList.Count)
    .Select(i => copyIList[i])
    .ToArray();

實際上是:

copy = Enumerable.Range(0, copyIList.Count)
    .Select<int, object>(i => copyIList[i])
    .ToArray<object>();

編譯器知道copyIList是一個 IList。 當您執行copyIList[i]時,您訪問IList 的 indexer ,它返回object 所以Select返回一個IEnumerable<object> ,因此ToArray()生成一個object[]

Array 有一個Clone 方法,可以讓你的生活更輕松:

((Array)original).Clone();

如果做不到這一點,您可以使用Array.CreateInstance實例化一個新數組。


對於 List 情況,使用 List 的構造函數會更容易,它需要另一個列表來復制:

public object Get_ListCopy(object original)
{
    Type elementType = original.GetType().GetGenericArguments()[0];
    Type listType = typeof(List<>).MakeGenericType(elementType);

    object copy = Activator.CreateInstance(listType, new[] { original });
    return copy;
}

暫無
暫無

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

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