Получите NHibernate.Collections.Generic.PersistentGenericBag как IList <T>, используя Reflection - PullRequest
2 голосов
/ 08 февраля 2010

Я пытаюсь сравнить график переходных объектов с сохраненным NHibernate-графиком объектов. К сожалению, мой код ломается, когда речь идет о свойствах типа IList<T>. Приведенный ниже код отлично работает с экземплярами List<T>, поскольку List<T> реализует оба IList<T> И IList. К сожалению, PersistentGenericBag NHibernate реализует только IList<T>.

IList list1 = (IList)prop1.GetValue(object1, null);
IList list2 = (IList)prop2.GetValue(object2, null);

Если объект1 или объект2 являются PersistentGenericBag, я получаю сообщение об ошибке, например:

System.Reflection.TargetInvocationException : Exception has been thrown
by the target of an invocation.
  ----> System.InvalidCastException : Unable to cast object of type
'NHibernate.Collection.Generic.PersistentGenericBag`1[MyNamespace.MyClass]'
to type 'System.Collections.Generic.List`1[MyNamespace.MyClass]'.

Существует ли надежный способ получения экземпляра PersistentGenericBag в виде IList с использованием отражения?

Я надеялся, что популярный класс Compare .NET Objects поможет, но он терпит неудачу с той же самой ошибкой.

Редактировать: Все ответы ниже находятся на правильном пути. Проблема заключалась в том, что метод получения проблемного свойства IList<T> пытался привести к List<T>, что явно невозможно сделать с PersistentGenericBag. Итак, моя вина за ошибочный вопрос.

Ответы [ 2 ]

3 голосов
/ 09 февраля 2010

РЕДАКТИРОВАТЬ: не важно. Комментатор прав, вы можете перейти прямо к IList. Я сосредоточил внимание на одном вопросе, который был сформулирован слишком сложно, чтобы увидеть очевидное, даже когда я кодировал ответ. DOH!

Хорошо, вам просто нужно копать немного глубже.

Базовым классом PersistentGenericBag является PersistentBag, который делает реализующим IList.

var prop1 = typeof (Customer).GetProperty("Invoice");

// if you need it for something...
var listElementType = prop1.PropertyType.GetGenericArguments()[0];

IList list1;


object obj = prop1.GetValue(object1, null);

if(obj is PersistentBag)
{
    list1 = (PersistentBag)obj;
}
else 
{
    list1 = (IList)obj;
}

foreach (object item in list1)
{
    // do whatever you wanted.
}

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

Итак, короткий ответ: Если вы ЗНАЕТЕ, что это сумка, вы можете просто привести объект сначала к PersistentBag, а затем к IList ...

IList list = (PersistentBag)obj;

Если вы НЕ ЗНАЕТЕ, тогда используйте условную логику, как показано.

1 голос
/ 08 февраля 2010

Вам не нужно IList для сравнения двух коллекций.

Вместо этого IEnumerable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...