объект [] из ReadOnlyCollection <T> - PullRequest
1 голос
/ 10 марта 2009

У меня есть объект, с которым я закончил вызовом отражения:

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

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

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

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

Ответы [ 5 ]

3 голосов
/ 10 марта 2009

Многие другие ответы упоминают 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

3 голосов
/ 10 марта 2009

Ну, вы можете использовать метод расширения Cast в коллекции readonly и затем преобразовать его в массив объектов, но, исходя из того факта, что в массивах c # * * Ковариант , вы можете просто сделать:

object[] objs = myReadOnlyCollection.ToArray();

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

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

(edit2)

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

1 голос
/ 10 марта 2009
 var myArray = readOnlyCollection.Cast<object>().ToArray(); 
0 голосов
/ 10 марта 2009

Приведите вашу коллекцию к списку объектов, затем вызовите ToArray ():

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

Работает только в C # 3.5 из-за методов расширения.

0 голосов
/ 10 марта 2009

Хотите глубокий клон коллекции? Если вы хотите глубокое клонирование, попробуйте этот код ниже для глубокого клонирования памяти:

// 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;
}
...