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