views:

336

answers:

5

I'm just trying to quickly debug a webservice by printing out the contents of an int and string array. Is there anyway to do this in one method?

I tried

public static string ArrayToString(object[] array)
{
    StringBuilder sb = new StringBuilder();

    foreach (Object item in array)
    {
     sb.Append(item.ToString());
     sb.Append(" ");
    }

    return sb.ToString();
}

But this chokes when I try and send it a primative array (int[]) due to it not being an Object.

Which I find strange as sending an int to the method below works

static void PrintObject(object obj)
{
    Console.WriteLine(obj.ToString());
}

Is there anyway to do this in one method or am I just going to have to man up and create two separate methods?


Of course whether I should be using arrays at all is questionable, but the web service is already in place.

See also:

+1  A: 
private string PrintObjects<T>(IEnumerable<T> objs)
{
    return string.Join(" ", objs.Select(o => o.ToString()).ToArray());
}
mquander
+4  A: 

Try something like this:

static String toString<T>(IEnumerable<T> list)
{
 StringBuilder sb = new StringBuilder();

 foreach (T item in list)
 {
  sb.Append(item.ToString());
  sb.Append(" ");
 }

 return sb.ToString();
}

The compiler will happily infer the type of T by the type of the list you pass in like this:

toString(new int[] { 1, 2, 3 });
toString(new String[] { "1", "2", "3" });
Andrew Hare
Works, awesome. Didn't realize that a primitive array would extend IList. Thanks.
James McMahon
You could just as easily use IEnumerable or ICollection, since you don't need to change the list or access elements by index (the primary distinguishing virtues of IList.)
mquander
@mquander, could you explain that point a little further?
James McMahon
@mquander: Excellent point! I corrected my answer.
Andrew Hare
The three interfaces IEnumerable<T>, ICollection<T>, and IList<T> all implement different functionality that one might associate with an "array" or a general sequence of things. IEnumerable is the simplest, and defines the ability only to go one by one and get each element (i.e. supports foreach.) ICollection is an IEnumerable, and represents a sequence that also has a definite length attached to it which you can add and remove things from (if it's not read-only.) IList is an ICollection that is in a definite order, so it lets you manipulate elements by index, like you can with an array.
mquander
For more information, I suggest you check out the MSDN docs for each interface, because they'll tell you exactly what methods they support, but that's the Cliffs Notes version.
mquander
(A Dictionary/Hashtable is an example of something that's an IEnumerable and an ICollection -- it has a count of elements and you can add and remove elements -- but it's not an IList, because you can't ask for the "first" element of a hash table.)
mquander
@mquander, thank you for taking the time to write that. Once you understand the hierarchy there, IEnumerable makes perfect sense. I gave your answer a vote up due to your comments here.
James McMahon
+2  A: 

Why did you choose an array? Your code depends on none of the specific properties of an array and instead just sees a list of objects. It seems like IEnumerable would be a much better choice and would allow for virtually any collection of objects

public static string ArrayToString(IEnumerable source)
{
    StringBuilder sb = new StringBuilder();

    foreach (Object item in source)
    {
        sb.Append(item.ToString());
        sb.Append(" ");
    }

    return sb.ToString();
}
JaredPar
I agree but the web service is already in place and working well.
James McMahon
I think IEnumerable<T> would be better as that would prevent any boxing when you iterate the collection.
Andrew Hare
+4  A: 
public static string ArrayToString<T>(T[] array)
{
   StringBuilder sb = new StringBuilder();

    foreach (T item in array)
    {
        sb.Append(item.ToString());
        sb.Append(" ");
    }

    return sb.ToString();
}

Then

int[] x = new int[] { 1, 2, 3 };

string[] y = new string[] { "a", "b", "c" };

Console.WriteLine(ArrayToString(x));
Console.WriteLine(ArrayToString(y));
Eoin Campbell
I think I like this solution the best, nice use of generics. I should have thought of this.
James McMahon
+1  A: 

There are a few ways to do this.

If you have Linq, you could do

int[] foo = new int[] {1,2,3,4};
ArrayToString(foo.Cast<Object>().ToArray());

and then send it.

Or, you could make a generic extension method

public static string ToString<T>(this IEnumerable<T> val)
{
    StringBuilder sb = new StringBuilder();
    foreach(var item in val) 
    {
       sb.Append(item.ToString());
       sb.Append(" ");
    }
    return sb.ToString();
}
Mike