我有一个通过反射调用结束的对象:
object readOnlyCollectionObject = propertyInfo.GetValue(someEntity, null);
我知道这个对象是一个通用的ReadOnlycollection。它可以是ReadOnlyCollection<Cat>
,ReadOnlyCollection<Dog>
等。为了论证,我们只能说它是ReadOnlyCollection<T>
。
即使Dog来自某个对象,我知道ReadOnlyCollection<Dog>
并非来自ReadOnlyCollection<object>
。因此,即使我使用反射来调用CopyTo方法,我仍然需要知道ReadOnlyCollection的特定类型,这是我想要避免的。
我想知道如何将ReadOnlyCollection中的所有元素作为对象引用数组,而不必知道ReadOnlyCollection<T>
的特定类型(T)。
答案 0 :(得分:3)
好吧,您可以在 readonly 集合上使用Cast扩展方法,然后将其转换为对象数组,但是,基于c#数组中的事实协变,你可以简单地做:
object[] objs = myReadOnlyCollection.ToArray();
(编辑)
正如Pop Catalin所提到的,只有T
是引用类型才有效。否则使用Cast方法。
(EDIT2)
你对这个问题的更新会改变一些事情...我认为你想要做的事情是不可能的。您希望转换为编译时的显式类型,该类型仅在运行时中可用。在这种情况下,您必须访问该集合的唯一方法是使用反射。
答案 1 :(得分:3)
许多其他答案提到Cast()和ToArray,这些都有类型的问题。如你所说,你不会知道你的财产将实施哪个专门的IEnumerable。但是,您可以确定它们都将实现非通用ICollection接口。
ICollection readOnlyCollectionObject = (ICollection)propertyInfo.GetValue(someEntity, null);
object[] objs = new ArrayList(readOnlyCollectionObject).ToArray();
或
ICollection readOnlyCollectionObject = (ICollection)propertyInfo.GetValue(someEntity, null);
object[] objs = new object[readOnlyCollectionObject.Count];
for (int i = 0; i < readOnlyCollectionObject.Count; i++)
objs[i] = readOnlyCollectionObject[i];
编辑:忘记将演员阵容从IEnumerable更新为ICollection
答案 2 :(得分:1)
var myArray = readOnlyCollection.Cast<object>().ToArray();
答案 3 :(得分:0)
将您的集合转换为对象列表,然后调用ToArray():
ReadOnlyCollection<string> s;
object[] o = s.Cast<object>().ToArray();
由于扩展方法,仅适用于C#3.5。
答案 4 :(得分:-1)
您想要深入克隆该集合吗?如果你想深度克隆,请尝试使用下面的代码进行内存深度克隆:
// deep copy in separeate memory space
public object Clone()
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, this);
ms.Position = 0;
object obj = bf.Deserialize(ms);
ms.Close();
return obj;
}