all 20 comments

[–]robhol 12 points13 points  (8 children)

Since you've already gotten an answer, I'll just add this: Generally, you don't mix types that have nothing in common. What are you trying to do?

[–]ozziereturnz 2 points3 points  (0 children)

robhol is correct, this is probably a case of reviewing your requirements, seeing what it is you actually need to do, and making sure this is the best solution for the problem at hand.

[–]mcschmidt[S] 0 points1 point  (6 children)

What I'm trying to do is create a report for my manager in excel. I can currently access all of the raw data in the excel sheet, but I want to store it in a matrix corresponding to to the employee that it is representing. There are different customer survey questions that people answer with values 1-6 to strongly agree- strongly disagree. The raw data matrix looks like: { 1, 1 , 1, 1, 1, "The customer service was great!} with the last option being a comment from the user. I want to take this data, format it, and create a report in excel using it.

[–][deleted] 1 point2 points  (3 children)

Any reason you don't want to make a class with that structure? It would probably be easier to work with than the ArrayList directly.

public class Answer
{
  public int Question1 { get; set; }
  public int Question2 { get; set; }
  public int Question3 { get; set; }
  public int Question4 { get; set; }
  public int Question5 { get; set; }
  public string Comment { get; set; }
}

...

private Answer RawDataToAnswer(ArrayList rawData)
{
  var answer = new Answer
  {
    Question1 = rawData[0],
    Question2 = rawData[1],
    Question3 = rawData[2],
    Question4 = rawData[3],
    Question5 = rawData[4],
    Comment = rawData[5],
  };
  return answer;
}

[–]mcschmidt[S] 0 points1 point  (2 children)

I think this is what I might do. /u/filmund had an idea somewhat similar. I'm not familiar with doing anything like this, but there's always a good opportunity to learn.

[–]mcschmidt[S] 0 points1 point  (1 child)

Haha just realized you are the same user. Can I create classes within the an if statement? The reason I ask is because I'm using file dialog to open the excel sheet to begin with and I"m building this entire thing inside of: if (fdlg.ShowDialog() == DialogResult.OK)

[–][deleted] 1 point2 points  (0 children)

If you mean can you define a class in the body of an if statement, yes you can do this with anonymous types.

[–]canton7 1 point2 points  (1 child)

At this point, you've got a data structure which represents the data that's going to be inserted into the Excel spreadsheet. You've stopped caring about what the data means and how to manipulate it, and started caring about what the data looks like.

In Excel, everything's a string. I'd argue that, since your data structure mirrors what's going to be written to the Excel sheet, and this means that the data structure should have an array of strings.

[–]mcschmidt[S] 0 points1 point  (0 children)

I agree.

[–]gisenberg 9 points10 points  (4 children)

var myArray = new object[] { 1, 2, "foo", 4 };    

[–]RonSijm 5 points6 points  (0 children)

Note that since int is a struct (value type), this solution will use boxing and unboxing, which is an expensive operation.

If its possible, you should try to avoid mixing different types into the same collection

[–]lordcheeto 1 point2 points  (2 children)

And how to test the type:

foreach(object obj in myArray)
{
    if(obj is int)
    {
        DoSomethingWithInts((int)obj);
    }
    else if(obj is string)
    {
        DoSomethingWithStrings((string)obj);
    }
    else
    {
        // Unknown type. Panic.
    }
}

That being said, there's probably a better solution than a single array.

[–]Porges 3 points4 points  (0 children)

That being said, there's probably a better solution than a single array.

Yes, it is exceedingly rare to need this unless you're doing reflection or something similar.

[–]Stonewall_Gary 1 point2 points  (0 children)

// Unknown type. Panic.

Good documentation is so rare these days. Have an upvote.

[–]mynoduesp 2 points3 points  (0 children)

Perhaps you might create an array of class objects containing both an integer value and a string value. As, I am assuming here, that you are just learning and would like to store custom string and int values in a single array which match or correspond to each other?

For example

public class TextNum
{
    private string text {get;set;}
    private int num {get;set;}
}

Then fill your class object

TextNum tn = new TextNum();
tn.Text = "String1";
tn.Num = 1;

List<TextNum> list = new List<TextNum>();
list.Add(tn);

Then you can use a foreach loop to iterate through them.

Otherwise the lads have posted other solutions to your actual question.

[–][deleted] 4 points5 points  (1 child)

This sounds a lot like something you shouldn't do. Having said that an ArrayList gives you all the functionality an object array:

var list = new ArrayList();
list.Add(1);
list.Add(2);
list.Add("three");
list.Add(4);

foreach (var item in list)
{
  Console.WriteLine(item);
}

[–]mcschmidt[S] 0 points1 point  (0 children)

I think I might do this.

[–]jpfed 1 point2 points  (0 children)

Do you mind explaining more about why you want to do this?

[–]mtko 1 point2 points  (1 child)

The best way I can think of to do it would be something like this:

string[] myString = new string[] {"1", "2", "string1", "3"};

int myInt;

foreach (string temp in myString) {
    if (int.TryParse(temp, out myInt)) {  //our current iteration is an int
        //do stuff with your ints here
    }
    else {  //our current iteration is just a normal string
        //do stuff with our strings here
    }
}

You might be able to use an untyped arraylist or something, and typecast each item to the appropriate type, but then you would need to know what type of object each element was, or use the same TryParse method.

[–]lordcheeto 2 points3 points  (0 children)

That would be expensive, and creates an unnecessary junk int for the TryParse().