We have a boxed list of strings:
object myList = new List<string> { "str1", "str2" };
We want to use String.Join
and obtain "str1,str2"
. If we do
String.Join(",",myList)
It returns System.Collections.Generic.List`1[System.String]
instead.
How do we deal with this without changing the declaration of myList
?
This is just a specific example. The type need not always be List<string>
, we need to do myList.GetType()
to obtain that info.
CodePudding user response:
If you don't know the type of the boxed collection, you could write a helper method to unbox and join it:
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");
}
}
Usage:
object myList = new List<string> { "str1", "str2" };
Console.WriteLine(UnboxAndJoin(",", myList)); // str1,str2
CodePudding user response:
You are getting System.Collections.Generic.List`1[System.String]
and that's the expected result in your case.
The overload resolution for String.Join
is chosing the following overload in your case:
public static string Join (string? separator, params object?[] values);
As documented here the Object.ToString()
method is called on each object of the values
parameter. Quotes from the documentation:
The string representation of each object in the array is derived by calling that object's ToString method.
The only object in the values
parameter is an instance of the List<string>
class. This class doesn't override the base implementation of ToString()
defined in the Object
class, so the fully qualified name of the class is returned when ToString()
is called on any instance of the class itself.
That's why you are getting the string System.Collections.Generic.List`1[System.String]
as the output of your code.
If your desired output is the string "str1,str2"
, then the overload of String.Join
that you really want to call is the following:
public static string Join (string? separator, System.Collections.Generic.IEnumerable<string?> values);
In order to call this overload, you need to downcast the myList
variable to the List<string>
type:
String.Join(",", (List<string>) myList)
If don't know the actual type of the object that you have in the myList
variable, you can be defensive and do the following:
if (myList is IEnumerable<string> values)
{
var message = String.Join(",", values);
Console.WriteLine(message);
}