0

My question is related to arrays in c#, or what I think is an array. I have a good knowledge in the basics of c# but not much after that.

I have been tasked to make changes to a piece of code below. The code retrieves a list of records from a web service and stores them in what I might be wrongly thinking is an array. Im not sure if arrays can have keys or "columns" like below (PurchaseDate, Location etc..). If not an array what is it?

OO_WebService.Sale[] saleList= OO_webService_connection.GetSales().Sales;

Console.Writeline(saleList[0].PurchaseDate);
Console.Writeline(saleList[0].Location);

Console.Writeline(saleList[1].PurchaseDate);
Console.Writeline(saleList[1].Location);

I also need to print out all keys or column names. For example there are another 20 keys along with PurchaseDate and Location. I want to be able to print out all key names(PurchaseDate) along with their values(01/04/2014 etc..) using a for loop, for example. I know it is possible in javascript. I have tried a few times but had no luck implementing it. Any suggestions greatly appreciated.

jww
  • 97,681
  • 90
  • 411
  • 885
user1843155
  • 61
  • 1
  • 3
  • Yes, it is an array, a `Sale[]` and that are propertis of the class `Sale`. You could get the names via reflection, but why do you need it at all? You know all properties, just use [Visual Studio's intellisense](http://msdn.microsoft.com/en-us/library/vstudio/hcw1s69b.aspx). – Tim Schmelter Sep 20 '14 at 20:56
  • [ ] means it's an array – kidshaw Sep 20 '14 at 21:00

3 Answers3

2

You need to use reflection...

var props = saleList.GetType().GetElementType().GetProperties();

foreach (var sale in saleList)
{
    foreach (var p in props)
    {
        Console.WriteLine(p.Name + "=" + p.GetValue(sale,null));
    }
    Console.WriteLine();
}
EZI
  • 15,209
  • 2
  • 27
  • 33
  • I wonder why the most frequent question of C# beginners is about reflection. – Tim Schmelter Sep 20 '14 at 21:05
  • 1
    @TimSchmelter Maybe it is hidden in this sentence `I know it is possible in javascript` – EZI Sep 20 '14 at 21:07
  • You can also do `Console.WriteLine("{0} = {1}", p.Name, p.GetValue(sale, null));` to avoid string concatenation which can be slow. That method converts to `Console.WriteLine(String.Format("{0} = {1}, p.Name, p.GetValue(sale, null));`. [MSDN on String.Format](http://msdn.microsoft.com/en-us/library/system.string.format(v=vs.110).aspx) – Spans Sep 20 '14 at 21:09
  • 1
    @Spans sample code is just to show how to use the reflection, and reflection is not known with its good performance, So avoiding string concatenations wouldn't bring much, (But can be thought of as better coding style which is out of scope of this question) – EZI Sep 20 '14 at 21:14
  • 1
    One minor tweak I would do is, we already know the type we are dealing with.. I would shorten `saleList.GetType().GetElementType().GetProperties();` to `typeOf(Sale).GetProperties();`.. i.e. EZI's solution is a little too generic :) nothing wrong, but why pay the cost with extra code and reflection. – Vikas Gupta Sep 20 '14 at 21:32
  • @VikasGupta `but why pay the cost with extra code` thanks for improving it a few nano sec. – EZI Sep 20 '14 at 21:38
1

The array in this case contains Sale elements. An array in C# is just a fixed-size collection of elements, and can contain either primitive types (such as int[] which you may be familiar with) or objects which is the case you're dealing with.

Instead of referring to saleList[0].PurchaseDate, you could rewrite that code as:

for (int i = 0; i < saleList.Lenght; i++)
{
    OO_WebService.Sale sale = saleList[i];
    Console.WriteLine(sale.PurchaseDate);
    Console.WriteLine(sale.Location);
}

So each element, accessed by saleList[index] is an instance of the Sale class. I hope that clears things up for you.

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72
0

You could use right-click on Sale and in the menu select 'Go To Definition'. That will give you all the properties. If Sale is dynamic (e.g., can have more or less properties at a later time), you can use reflection (as Tim said). This can be done as follows:

Type type = typeof(Sale);
PropertyInfo[] info = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
foreach (var i in info)
{
    Debug.WriteLine(i.Name + " = " + i.GetValue(this, null));
}

Note that the return value of GetValue is object and maybe needs to be casted to the correct type. Debug.WriteLine will call the objects default ToString() implementation.

Sjips
  • 1,248
  • 2
  • 11
  • 22
  • 1
    `If Sale is dynamic (e.g., can have more or less properties at a later time), you can use reflection` No. if it is *dynamic*, you can't use reflection – EZI Sep 20 '14 at 21:22
  • I think that is too generalized http://stackoverflow.com/questions/2634858/how-do-i-reflect-over-the-members-of-dynamic-object – Tim Schmelter Sep 21 '14 at 00:03