Как мне присоединиться к коллекции, если я не знаю ее тип во время компиляции?

У нас есть коробочный список строк:

object myList = new List<string> { "str1", "str2" };

Мы хотим использовать String.Join и получить "str1,str2". Если мы сделаем

String.Join(",",myList)

Вместо этого он возвращает System.Collections.Generic.List`1[System.String]. Как нам справиться с этим, не меняя декларацию myList?

Это просто конкретный пример. Тип не всегда должен быть List<string>, нам нужно сделать myList.GetType(), чтобы получить эту информацию.

"объект myList = новый список <строка>" - почему вы хотите это сделать?
MickyD 23.04.2022 10:56

Это всего лишь МВУ. Основной код включает в себя отражение, и мы имеем дело с объектами.

Arvind Ganesh 23.04.2022 10:57

Мм, вернуть его обратно в List<string>?

41686d6564 stands w. Palestine 23.04.2022 10:58
«Это просто MWE. Основной код включает в себя отражение, и мы имеем дело с объектами» — так что это пример ХУ вопрос. Рассмотрите возможность опубликовать свою проблему действительный
MickyD 23.04.2022 10:59
List<string> myList = new List<string> { "str1", "str2" };
Ibram Reda 23.04.2022 11:01

@41686d6564standsw.Палестина, пожалуйста, смотрите редактировать

Arvind Ganesh 23.04.2022 11:01

@MickyD реальная проблема не намного больше. Нам нужна строка из списка, полученного с помощью FieldInfo.GetValue, а затем мы записываем ее в ячейку файла .csv. Но сейчас он печатает System.Collections.Generic.List`1[System.String] вместо фактического списка.

Arvind Ganesh 23.04.2022 11:09
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
7
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если вы не знаете тип упакованной коллекции, вы можете написать вспомогательный метод для распаковки и присоединения к ней:

public string UnboxAndJoin(string separator, object obj)
{
    if (obj is IEnumerable enumerable)
    {
        return string.Join(separator, enumerable.Cast<object>());
    }
    else
    {
        throw new ArgumentException("Object is not an IEnumerable");
    }
}

Использование:

object myList = new List<string> { "str1", "str2" };
Console.WriteLine(UnboxAndJoin(",", myList));       // str1,str2

Вы получаете System.Collections.Generic.List`1[System.String], и это ожидаемый результат в вашем случае.

Разрешение перегрузки для String.Join в вашем случае выбирает следующую перегрузку:

public static string Join (string? separator, params object?[] values);

Как задокументировано, здесь вызывается Object.ToString() метод для каждого объекта параметра values. Цитаты из документации:

The string representation of each object in the array is derived by calling that object's ToString method.

Единственный объект в параметре values — это экземпляр класса List<string>. Этот класс не переопределяет базовую реализацию ToString(), определенную в классе Object, поэтому полное имя класса возвращается, когда ToString() вызывается для любого экземпляра самого класса.

Вот почему вы получаете строку System.Collections.Generic.List`1[System.String] в качестве вывода вашего кода.

Если желаемый результат — это строка "str1,str2", то перегрузка String.Join, которую вы действительно хотите вызвать, выглядит следующим образом:

public static string Join (string? separator, System.Collections.Generic.IEnumerable<string?> values);

Чтобы вызвать эту перегрузку, вам нужно преобразовать переменную myList в тип List<string>:

String.Join(",", (List<string>) myList)

Если вы не знаете фактический тип объекта, который у вас есть в переменной myList, вы можете защищаться и сделать следующее:

if (myList is IEnumerable<string> values) 
{
  var message = String.Join(",", values);
  Console.WriteLine(message);
}

Другие вопросы по теме