2009-03-10 2 views
1

У меня есть объект, который я закончил с помощью вызова отражения:объекта [] из ReadOnlyCollection <T>

object readOnlyCollectionObject = propertyInfo.GetValue(someEntity, null);

Я знаю, этот объект является общим ReadOnlyCollection. Это может быть ReadOnlyCollection<Cat>, ReadOnlyCollection<Dog> и т. Д. Для аргументации просто скажем, что это ReadOnlyCollection<T>.

Несмотря на то, что собака происходит от объекта, я знаю, что ReadOnlyCollection<Dog> не является результатом ReadOnlyCollection<object>. Поэтому, даже если я использую отражение для вызова метода CopyTo, мне все равно нужно знать определенный тип ReadOnlyCollection, чего я хочу избежать.

Я хочу знать, как получить все элементы из ReadOnlyCollection как массив ссылок на объекты без необходимости знать конкретный тип (T) ReadOnlyCollection<T>.

ответ

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

+0

Проблема в первой строке не будет скомпилирована, потому что вы не можете конвертировать из IEnumerable в ICollection. – hkdk3107

+0

Изменено. Должно быть, это опечатка с твердым оглавлением. – erikkallen

+0

Это решение очень аккуратно, потому что оно вообще не заботится о дженериках. – hkdk3107

3

Ну, вы можете использовать метод Cast расширения на сборе в чтения, а затем преобразовать его в массив объектов, но, основываясь на том, что в C# массивы являются ковариантны, вы можете просто сделать:

object[] objs = myReadOnlyCollection.ToArray(); 

(редактировать)

Как уже упоминалось Поп Каталин, только работает, если T является ссылочным типом. Используйте метод Cast в противном случае.

(edit2)

Ваше обновление к вопросу изменяет вещи совсем немного ... Я думаю, что то, что вы пытаетесь сделать, это не представляется возможным. Вы хотите использовать явный тип в времени компиляции, который доступен только по адресу runtime. В этом случае единственным способом доступа к коллекции является отражение.

+0

Массивы ссылочных типов ковариантны, это будет работать только тогда, когда T является ссылочным типом. –

+0

Пожалуйста, посмотрите еще раз. Я обновил описание, чтобы показать, как я получил этот объект. – hkdk3107

+0

humm. Это немного меняет ситуацию. Посмотрите мое второе обновление. –

-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; 
} 
0

Cast своей коллекции в список объектов, а затем вызвать ToArray():

ReadOnlyCollection<string> s; 
object[] o = s.Cast<object>().ToArray(); 

работает только в C# 3.5, поскольку методов расширения.

 Смежные вопросы

  • Нет связанных вопросов^_^