Получение типа списка , который является пустым

#c# #list #casting

#c# #Список #Кастинг

Вопрос:

 List<SomeClass> classObject = new List<SomeClass>();
someClass = .....
classObject.Add(someClass);

// For some reason we need to cast this List to List<object>.
List<object> objectList = classObject.Cast<object>().ToList();

// The receiving end will try then cast the item using the items in the objectList
var newInstance = Assembly.GetExecutingAssembly().CreateInstance(objectList[index].GetType().FullName);
 

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

Есть ли что-нибудь вокруг него, не передавая тип SomeClass ?

Я пробовал GetGenericArguments, но потерпел неудачу, поскольку он возвращает System .Объект, который мы не можем использовать.

Комментарии:

1. нет проверки, чтобы проверить, пуст ли список, прежде чем пытаться получить доступ к его элементам?

2. Я собираюсь предположить и сказать «нет», другого способа нет. Ваш список относится к типу object , который, не содержащий экземпляра someClass , потенциально может содержать больше или меньше чего угодно. Как компилятор должен знать, какой тип вы намеревались использовать или когда-то сохраняли в своем списке?

3. @ChetanRanpariya Приведенный выше пример приведен после проверки, не является ли список пустым, выполняемой другим классом расширения. Проблема, которую мы пытаемся решить здесь, заключается в поиске способа получить тип объекта без объекта в списке. Мы знаем, что в списке есть только один тип объекта.

4. @GeorgeKerwood Привет, Герой, мы подумали так же, как и о том, что он уже является базовым объектом, и обходного пути нет. Думаю, в этом случае мы также должны передать тип, но это действительно требует большого рефакторинга. У нас есть класс расширения, который преобразует class в datatable, list, xml, model и так далее. Все части могут работать хорошо, за исключением этой проблемы со списком, поскольку мы не можем создать правильную таблицу данных с пустым списком. 🙁

5. Если список пуст, какова цель попытки создать объект из элемента onexsiting из списка? Разве вы не получаете исключение при попытке получить доступ к элементу из пустого списка, выполнив objectList[index] ?

Ответ №1:

Прежде всего, предупреждение о том, что я считаю это «хакерским» решением, однако вы просите способ, так что вот он.

Проблема в том, что a List<object> не содержит необходимой нам информации. Если в списке есть элементы, вы можете обойти это, проверив элемент, но это, очевидно, не сработает, если в списке нет элементов.

Итак, нам нужно создать способ добавления необходимой нам информации в List<object> мы можем сделать это, создав свой собственный List<object> :

 public class MyTypedObjectList : List<object>
{
    public MyTypedObjectList(Type type)
    {
        MyType = type;
    }
    public Type MyType { get; }
}
 

И для простоты использования мы можем создать метод расширения для создания за нас:

 public static class EnumerableExtensions
{
    public static MyTypedObjectList ToMyTypedObjectList<T>(this IEnumerable<T> source)
    {
        var myTypedObjectList = new MyTypedObjectList(typeof(T));
        myTypedObjectList.AddRange(source.Cast<object>());
        return myTypedObjectList;
    }
}
 

Теперь мы можем сделать:

 List<object> objectList = classObject.ToMyTypedObjectList();
 

И используйте его как a List<object> во всем остальном коде.

Затем на принимающей стороне (поскольку мы используем один и тот же экземпляр) мы можем выполнить обратное приведение и получить тип, даже если список пуст:

 var myTypedObjectList = (MyTypedObjectList) objectList;
 

И, наконец, сделайте это:

 Assembly.GetExecutingAssembly().CreateInstance(myTypedObjectList.MyType.FullName);
 

Как уже было сказано, это хакерский способ, но если вы действительно этого хотели, это должно решить вашу проблему (но, пожалуйста, подумайте о рефакторинге и правильном решении этой проблемы)

Комментарии:

1. Спасибо за ваши усилия, халтурно, но работает. Поскольку текущий исходный код (который, как я полагаю) преобразует каждый чертов список <T> в список <object> перед пользовательским расширением, теперь будет достаточно быстрого поиска и замены плюс 4 блока кодов!