.NET Forum / Languages / C# / December 2005
How to do "Compile time" initialization of record array?
|
|
Thread rating:  |
John Kelsey - 30 Dec 2005 17:36 GMT Back in the "old" days with C, I used to do something like...
struct { char Description[20]; float price; } Items[] = { {"Apple", 1.99}, {"Banana", 2.04} };
If I wanted to do something similiar (and I do), does anyone have hints for an obviously new C# programmer?
Any help is greatly appreciated, John Kelsey
Dave - 30 Dec 2005 18:00 GMT That looks like a hashtable. So i would do...
Hashtable hashtable = new Hashtable(); hashtable.add("Apple", 1.99); hashtable.add("Banana", 2.04);
However you will have to know the key (e.g. 'Apple' or 'Banana') to refer to these items in the hashtable. I would recomend creating a new object with properties that you desire. Then create an ArrayList and add that object to the ArrayList.
John Kelsey - 30 Dec 2005 18:16 GMT Dave,
I appreciate the response but I was looking for something slightly different.
My array was initialized before runtime. I understand that I can add records to a "collection" as part of the program execution, but in C, the array contained the values I wanted without having to write one executable statement.
This may be a subtle point that C# doesn't support... it may just be my programming style...
I guess it boils down to the difference between int i = 32;
and int i; ... i = 32;
Is this any clearer?
> That looks like a hashtable. So i would do... > [quoted text clipped - 6 lines] > object with properties that you desire. Then create an ArrayList and > add that object to the ArrayList. Jon Skeet [C# MVP] - 30 Dec 2005 18:33 GMT > I appreciate the response but I was looking for something slightly > different. [quoted text clipped - 14 lines] > ... > i = 32; Well, in that case there really isn't any difference in the compiled code, as far as I'm aware. I know what you mean though :)
> Is this any clearer? While I see what you mean, there isn't a way of doing it that I know of in C#, nor do I suspect it's really a problem. Do you have any particular reason for desiring it from an execution point of view? You can achieve the same "end goal" (getting an initialised array) in C# with quite similar code, so it's only the matter of when it actually gets built which is significantly different. Are you worried about performance?
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
John Kelsey - 30 Dec 2005 18:55 GMT Jon,
For example, one of my "C" programs has
struct { double L; double M; double S; } LengthArray[] = { { 1.267004226, 49.988884080, 0.053112191}, // 1 { 0.511237696, 52.695975300, 0.048692684}, // 2 { -0.452244460, 56.628428550, 0.044116830}, // 3
This is some statistical data (there are 76 records per array) and I have Length, Weight, and Circumference arrays.
I typically am targeting some low "horsepower" handheld devices.
Even in C, I could run time initialize my arrays but I didn't for at least a couple of reasons... 1) Performance, why waste runtime cycles building an array when it could be pre-built by the compiler 2) Run time building meant that I carried two copies of my data in the "execution footprint". One copy in code segment and the other copy in the data segment.
I understand that this really doesn't present a challenge to a modern device, especially in a desktop environment, it was just a style I have/had.
I don't understand C# the way I do C. Things that used to be important, no longer seem to matter as much.
I've appreciated all of the responses and I'm certain I'll ask more "old fashioned" questions as I learn.
Thanks, John Kelsey
--snip--
>> I guess it boils down to the difference between >> int i = 32; [quoted text clipped - 16 lines] > gets built which is significantly different. Are you worried about > performance? Jon Skeet [C# MVP] - 30 Dec 2005 19:12 GMT > For example, one of my "C" programs has > [quoted text clipped - 20 lines] > "execution footprint". One copy in code segment and the other copy in the > data segment. In both of these cases, I'd expect the time and memory taken to be really pretty tiny. You'll be wasting a few K and a couple of milliseconds (once), even on a handheld device. These days, that's not likely to be a significant problem.
> I understand that this really doesn't present a challenge to a modern > device, especially in a desktop environment, it was just a style I have/had. Sure.
> I don't understand C# the way I do C. Things that used to be important, no > longer seem to matter as much. Indeed. However, the things which were a real pain in C are much easier in C# and .NET. Modern languages tend to value the time of the developer over the time of the processor, on the grounds that it's generally a lot more expensive :)
> I've appreciated all of the responses and I'm certain I'll ask more "old > fashioned" questions as I learn. Goodo. Do keep 'em coming.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Nicholas Paldino [.NET/C# MVP] - 30 Dec 2005 20:04 GMT It should be noted that there is proposed syntax for C# 3.0 which will allow initialization with the following syntax:
public struct MyStruct { public double L; public double M; public double S; }
MyStruct[] lengthArray[] = new MyStruct[] { { L = 1.267004226, M = 49.988884080, S = 0.053112191}, { L = 0.511237696, M = 52.695975300, S = 0.048692684}, { L = -0.452244460, M = 56.628428550, S = 0.044116830} }
I might have not gotten it completely correct, but the syntax is something like that.
What actually gets compiled is the same array initialization as there is now, but code that will actually populate the properties/fields like regular assignments. It's been a while since I used the C# 3.0 preview, but the proposed spec amendments go into much more detail.
 Signature - Nicholas Paldino [.NET/C# MVP] - mvp@spam.guard.caspershouse.com
>> For example, one of my "C" programs has >> [quoted text clipped - 48 lines] > > Goodo. Do keep 'em coming. Dave - 30 Dec 2005 19:17 GMT I never learned C. I started programming with the introduction of Java so I'm sure im unfamiliar with old techniques. But I dont think there is a way to initialize an array at compile time in C#. I have a question about C since i am unfamiliar to it. How does it fill an array at compile time, isn't an array just a cached set of objects? If it caches the objects at compile time then that means only the machine that compiles the program can access the array and only after it has been compiled.
About your program. I think your best bet is to create and object with different properties and then add them to an ArrayList. e.g.....
public class Veggies { private static int L; private static int M; private static int S; public Veggies(int l, int m, int s) { L = l; M = m; S = s; } public static int L() { get {return L;} } ... ... }
//in your other class private ArrayList list = new ArrayList(); Veggies oVeggies = new Veggies(1.267004226, 49.988884080, 0.053112191); list.Add(oVeggies); Veggies oVeggies = new Veggies(0.511237696, 52.695975300, 0.048692684); list.Add(oVegges); //... //and so on...
Hope this helped.
John Kelsey - 30 Dec 2005 19:54 GMT Dave,
The answer to you question is a little complicated and probably out of scope for this newsgroup, but... You could simplistically think of old C programs as having: 1) a Data segment, "long term" variable storage but only lasts as long as the program (think global variables) 2) a Code segment, executable statements (mostly code, but some data) 3) a stack for "short term" variable storage
For compiler initialized variables, the compiler would create an image of the data segment that had certain values already set. The program loader would load the program with the initialized data segment and the first executable statement in the program had access to the data segment image/compiler initialized variables.
All of the work is done by the compiler and the program loader, not by the code I write.
This is highly simplified, but I hope you get the point. A point of interest but probably only of value if you ever take ancient computer languages subject.
Thanks for the help. John Kelsey
>I never learned C. I started programming with the introduction of Java > so I'm sure im unfamiliar with old techniques. But I dont think there [quoted text clipped - 4 lines] > that compiles the program can access the array and only after it has > been compiled. --snip--
Christoph Nahr - 30 Dec 2005 20:50 GMT John,
I've also learned C programming before I ever heard of .NET and I'm always happy to help a fellow dinosaur. :)
One big difference between C and C# is that all .NET arrays are always located on the (managed, garbage-collected) heap. There is no such thing as a pre-allocated, pre-initialized array in C#.
You can have simple constants (including strings which are special in .NET) that are evaluated at compile time and stored in the executable image, but you can't have arrays that are stored in this way. (.NET strings are _not_ character arrays, they are a separate data type.)
So while C# does syntactically allow initializing arrays in a single big statement, you actually don't gain anything over assigning each array element in a separate statement. The array itself is always allocated at runtime on the heap, and all initialization statements are therefore also evaluated at runtime. There's no way around this.
Hope this explains things, Chris
>Dave, > [quoted text clipped - 21 lines] >Thanks for the help. >John Kelsey  Signature http://www.kynosarges.de
Dave - 30 Dec 2005 18:40 GMT John,
If I'm understanding you correctly, what you want to do is have an array established before your program runs. Is this correct? I think I was trying to do something like this a few days ago. I wanted to have a constant hashtable. Since I don't think this is possible, I created an object that was going to contain this hashtable. Then I declared all the constants that I wanted to be in the hashtable and then in the contructor I added them to the hashtable. Then when ever I call this object the hashtable is already filled. You can call initialize this object at load time so that the array is cached for the remaining run time. I made this object a singleton because everything in this object is constant. This keeps my cache smaller for better performance. Hope this helps.
Jon Skeet [C# MVP] - 30 Dec 2005 18:23 GMT > Back in the "old" days with C, I used to do something like... > [quoted text clipped - 10 lines] > If I wanted to do something similiar (and I do), does anyone have hints for > an obviously new C# programmer? Well, firstly I'd separate the declaration of the type from the use of it. I'd then provide a constructor which took the description and the price, and use that. For instance:
using System;
public class Item { string description; public string Description { get { return description; } } // Note change to use the decimal type, // which is usually more appropriate than float // for money decimal price; public decimal Price { get { return price; } } public Item (string description, decimal price) { this.description = description; this.price = price; } }
public class Test { static void Main() { Item[] items = { new Item ("Apple", 1.99m), new Item ("Banana", 2.0m) }; foreach (Item item in items) { Console.WriteLine ("{0} costs {1}", item.Description, item.Price); } } }
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Peter Bromberg [C# MVP] - 30 Dec 2005 18:29 GMT if you want it to be an array of Veggie Structs, something like:
struct Veggie { string Description; decimal Price; public Veggie(string description, decimal price) { Description =description; Price = price; } }
//usage: Veggie[] Items =new Veggie[] {new Veggie("Pear",2.99), new Veggie("Avocado", 5.13), ....};
(untested) --Peter
 Signature Co-founder, Eggheadcafe.com developer portal: http://www.eggheadcafe.com UnBlog: http://petesbloggerama.blogspot.com
> Back in the "old" days with C, I used to do something like... > [quoted text clipped - 13 lines] > Any help is greatly appreciated, > John Kelsey Marina - 30 Dec 2005 19:27 GMT I believe both Pears and Avocados are technically fruit :)
> if you want it to be an array of Veggie Structs, something like: > [quoted text clipped - 35 lines] >> Any help is greatly appreciated, >> John Kelsey Peter Bromberg [C# MVP] - 30 Dec 2005 19:57 GMT You don't have to go to Arizona to find Yuma.
 Signature Co-founder, Eggheadcafe.com developer portal: http://www.eggheadcafe.com UnBlog: http://petesbloggerama.blogspot.com
> I believe both Pears and Avocados are technically fruit :) > [quoted text clipped - 37 lines] > >> Any help is greatly appreciated, > >> John Kelsey Jon Skeet [C# MVP] - 30 Dec 2005 20:05 GMT > I believe both Pears and Avocados are technically fruit :) I was going to point that out, but I wouldn't want Peter to think me a pedant ;)
Arguably you could say that fruit are vegetables anyway, according to some definitions. If you look at http://www.google.com/search?q=define%3Avegetable about half the definitions would include fruit, although possibly unintentionally...
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
eye5600 - 30 Dec 2005 21:10 GMT int[] pins = new int[4] {9,3,7,2} ;
Damned if I know what really happens in the compiler, but it looks like the above means the array is created at compile time but the address is transferred to pins at execution. Or maybe not.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|