Using an array as a Class member

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I would like to set up a string array as a class member, or field, and then
populate this array by reading in from a text file, but I cannot find the
appropriate syntax. The getter and setter are very unhappy with the idea and
the compiler refuses to play ball with any of the attempts I have made to
build such a structure. There is no problem when using a single string but a
two dimensional array of strings appears to be a very different matter.

In the 'good old days' of classical 'C', I would simply have passed a
pointer to the array but the 'good old days' have gone. Am I simply getting
too old for this game, or will some kind soul show me how it is done?
 
Peter said:
I would like to set up a string array as a class member, or field, and then
populate this array by reading in from a text file, but I cannot find the
appropriate syntax. The getter and setter are very unhappy with the idea and
the compiler refuses to play ball with any of the attempts I have made to
build such a structure. There is no problem when using a single string but a
two dimensional array of strings appears to be a very different matter.

In the 'good old days' of classical 'C', I would simply have passed a
pointer to the array but the 'good old days' have gone. Am I simply getting
too old for this game, or will some kind soul show me how it is done?
public string[,,] Foo
{
get
{
return new string[10,10,10];
}
}

This will return a three dimensional array (thank you captain obvious :)).
Single = string[]
Double = string[,]

HTH

JB
 
Peter Hallett said:
I would like to set up a string array as a class member, or field, and then
populate this array by reading in from a text file, but I cannot find the
appropriate syntax. The getter and setter are very unhappy with the idea and
the compiler refuses to play ball with any of the attempts I have made to
build such a structure. There is no problem when using a single string but a
two dimensional array of strings appears to be a very different matter.

I'm not sure exactly what you mean by a two-dimensional array of
strings. If you said a two-dimensional (but jagged) array of characters,
I could understand, but that isn't the normal approach in C# for dealing
with strings. Instead, a single-dimensioned array of strings is more
normal.

---8<---
class Foo
{
string[] _lines;

public void LoadFromFile(string fileName)
{
// The .NET 2.0 way:
_lines = File.ReadAllLines(fileName);

// or the old-fashioned way:
string line;
ArrayList lines = new ArrayList();
using (TextReader reader = File.OpenText(fileName))
while ((line = reader.ReadLine()) != null)
lines.Add(line);
_lines = (string[]) lines.ToArray(typeof(string));
}
}
--->8---
In the 'good old days' of classical 'C', I would simply have passed a
pointer to the array but the 'good old days' have gone. Am I simply getting
too old for this game, or will some kind soul show me how it is done?

In the above code, a string[] value (i.e. _lines, for example) is a
reference to the array on the heap. The array itself is an array of
references to the string values on the heap, since string is also a
reference type. So, to pass around the array, one literally passes
around values of type string[].

-- Barry
 
Sorry if I confused you. I simply meant:-
1 dimensional array = string[]
2 dimensional array = string[,]
3 dimensional array = string [,,]
The source .txt file consists of 34 pairs of comma delimited values but the
values themselves vary according to the application. The first job, before
running Main is thus to read in the appropriate file and store the values as
members of a Class in the form eg [0.1, 2.2]
[1.3, 9.0]
[0.7, 3.112]
etc.,
etc.
I hope that makes things a bit clearer.
In the mean time, thank you for your help. I will study your reply and see
if I can make any more progess.


--
Peter Hallett


Barry Kelly said:
Peter Hallett said:
I would like to set up a string array as a class member, or field, and then
populate this array by reading in from a text file, but I cannot find the
appropriate syntax. The getter and setter are very unhappy with the idea and
the compiler refuses to play ball with any of the attempts I have made to
build such a structure. There is no problem when using a single string but a
two dimensional array of strings appears to be a very different matter.

I'm not sure exactly what you mean by a two-dimensional array of
strings. If you said a two-dimensional (but jagged) array of characters,
I could understand, but that isn't the normal approach in C# for dealing
with strings. Instead, a single-dimensioned array of strings is more
normal.

---8<---
class Foo
{
string[] _lines;

public void LoadFromFile(string fileName)
{
// The .NET 2.0 way:
_lines = File.ReadAllLines(fileName);

// or the old-fashioned way:
string line;
ArrayList lines = new ArrayList();
using (TextReader reader = File.OpenText(fileName))
while ((line = reader.ReadLine()) != null)
lines.Add(line);
_lines = (string[]) lines.ToArray(typeof(string));
}
}
--->8---
In the 'good old days' of classical 'C', I would simply have passed a
pointer to the array but the 'good old days' have gone. Am I simply getting
too old for this game, or will some kind soul show me how it is done?

In the above code, a string[] value (i.e. _lines, for example) is a
reference to the array on the heap. The array itself is an array of
references to the string values on the heap, since string is also a
reference type. So, to pass around the array, one literally passes
around values of type string[].

-- Barry
 
Thanks for your help. As an old (in both senses of the word) 'C' programmer
I currently feel as if I am wandering around in the C# coal cellar with the
lights off. No doubt it will all become clearer with time but meanwhile, I
am going to have to ask some dumb questions. (Why is it that the text books
always provide a plethora of information about things you don't want to know
yet leave out the vital stuff?)
--
Peter Hallett


John B said:
Peter said:
I would like to set up a string array as a class member, or field, and then
populate this array by reading in from a text file, but I cannot find the
appropriate syntax. The getter and setter are very unhappy with the idea and
the compiler refuses to play ball with any of the attempts I have made to
build such a structure. There is no problem when using a single string but a
two dimensional array of strings appears to be a very different matter.

In the 'good old days' of classical 'C', I would simply have passed a
pointer to the array but the 'good old days' have gone. Am I simply getting
too old for this game, or will some kind soul show me how it is done?
public string[,,] Foo
{
get
{
return new string[10,10,10];
}
}

This will return a three dimensional array (thank you captain obvious :)).
Single = string[]
Double = string[,]

HTH

JB
 
John said:
public string[,,] Foo
{
get
{
return new string[10,10,10];
}
}

Do you really want to construct a new string every time the property is
accessed?
 
Chris Dunaway said:
John said:
public string[,,] Foo
{
get
{
return new string[10,10,10];
}
}

Do you really want to construct a new string every time the property is
accessed?

You've got no better choice for properties which are arrays, since the
arrays are mutable through the interface you return. This is one of the
reasons why it isn't recommended that you make properties which are
arrays, and use collections instead.

-- Barry
 
Chris said:
John said:
public string[,,] Foo
{
get
{
return new string[10,10,10];
}
}

Do you really want to construct a new string every time the property is
accessed?
Most likely not. I just used it as the quickest way of illustrating how
to implement a string array property.

:)

JB
 
I am beginning to feel as if I am not only in the C# coal cellar with the
lights off but that someone has now placed a paper bag over my head. Perhaps
if I describe the application in a little more detail it will help to clarify
the situation?

I am converting an old ‘C’ program which formerly ran under DOS (indeed,
still does). It calculated weight and balance data for commercial aircraft.
The first part of the program solicited the aircraft make (eg Boeing), type
(eg 737-300, 400 or 500) and configuration (airstairs, spare nose wheel,
catering etc. carried or not) via a series of forms, the inputs to which
determine which sets of data are to be read from a collection of text files.
I have rebuilt this selection routine as a series of Windows Forms without
too many problems. The resulting unique index identifies one aircraft
make/type/configuration for which the corresponding data are to be retrieved
from the text files. These file data are then read into a series of arrays,
from where they are available to the calculation procedures. It is clearly
more efficient to load the required data in this way than to re-read it from
the files every time it is needed. At the same time, by determining first
which subsets of data are required, the amount of data dynamically stored in
memory is reduced to just that needed for the particular aircraft selection
being considered. It is the conversion of this bit of code which is
currently giving me problems.

As an example, of the data structure, the first file to be read in, lists
the weight and balance index for each tonne of fuel loaded (in half tonne
increments up to somewhat more than 16 tonnes). The text file thus has the
form 0.5, -0.01 [CR] 1.0, 0.2 [CR] 1.5, 0.36 [CR] 2.0, 1.194 [CR] etc. There
are 34 pairs of such numbers for the Boeing 737. As will be apparent, the
members of each pair are comma delimited whilst the pairs themselves are
separated by carriage returns. Unsurprisingly, this data was read into a 34
x 2 array. The other required data were similarly read into other arrays,
some of which were of one dimension; some were of two dimensions and a few
were three-dimensional.

C# now demands that I store this data in classes and it is here that I am
finding problems. When in memory, the data must be strictly read-only. Data
amendment is only permitted to specified personnel with access to the text
files. Certainly no program operation must be able to modify the data in any
way. Since the data has to be read in, from the text files, however, the
arrays cannot be declared read-only and, as already implied, there appears
little or no point in creating a new instance of the data every time the data
has to be used – suggesting the use of a static class, or classes.

If someone would suggest how best to use the getters and setters to input
this data and make it available to the subsequent calculation procedures
(sorry, methods) I would be very grateful.

--
Peter Hallett


Chris Dunaway said:
John said:
public string[,,] Foo
{
get
{
return new string[10,10,10];
}
}

Do you really want to construct a new string every time the property is
accessed?
 
Chris Dunaway said:
John said:
public string[,,] Foo
{
get
{
return new string[10,10,10];
}
}

Do you really want to construct a new string every time the property is
accessed?

<pedantry>
The above code doesn't create any new strings, just an empty array ;)
</pedantry>
 
Well, originally I was going to suggest that you really don't want an
array of strings, but actually a StringCollection.

However, Looking at your expanded explanation, I'd say you want a
List<NumPairs> where
class NumPairs
{
public string First;
public string Second;
}

Although it looks like what you really want is:
class NumPairs
{
public float First;
public float Second;
}



Peter said:
Sorry if I confused you. I simply meant:-
1 dimensional array = string[]
2 dimensional array = string[,]
3 dimensional array = string [,,]
The source .txt file consists of 34 pairs of comma delimited values but the
values themselves vary according to the application. The first job, before
running Main is thus to read in the appropriate file and store the values as
members of a Class in the form eg [0.1, 2.2]
[1.3, 9.0]
[0.7, 3.112]
etc.,
etc.
I hope that makes things a bit clearer.
In the mean time, thank you for your help. I will study your reply and see
if I can make any more progess.


--
Peter Hallett


Barry Kelly said:
Peter Hallett said:
I would like to set up a string array as a class member, or field, and then
populate this array by reading in from a text file, but I cannot find the
appropriate syntax. The getter and setter are very unhappy with the idea and
the compiler refuses to play ball with any of the attempts I have made to
build such a structure. There is no problem when using a single string but a
two dimensional array of strings appears to be a very different matter.

I'm not sure exactly what you mean by a two-dimensional array of
strings. If you said a two-dimensional (but jagged) array of characters,
I could understand, but that isn't the normal approach in C# for dealing
with strings. Instead, a single-dimensioned array of strings is more
normal.

---8<---
class Foo
{
string[] _lines;

public void LoadFromFile(string fileName)
{
// The .NET 2.0 way:
_lines = File.ReadAllLines(fileName);

// or the old-fashioned way:
string line;
ArrayList lines = new ArrayList();
using (TextReader reader = File.OpenText(fileName))
while ((line = reader.ReadLine()) != null)
lines.Add(line);
_lines = (string[]) lines.ToArray(typeof(string));
}
}
--->8---
In the 'good old days' of classical 'C', I would simply have passed a
pointer to the array but the 'good old days' have gone. Am I simply getting
too old for this game, or will some kind soul show me how it is done?

In the above code, a string[] value (i.e. _lines, for example) is a
reference to the array on the heap. The array itself is an array of
references to the string values on the heap, since string is also a
reference type. So, to pass around the array, one literally passes
around values of type string[].

-- Barry
 
Jon said:
<pedantry>
The above code doesn't create any new strings, just an empty array ;)
</pedantry>

Of course you're right, I should be more careful in my posts.
Especially when dealing with this group of people!! :)
 
Barry said:
Chris Dunaway said:
John said:
public string[,,] Foo
{
get
{
return new string[10,10,10];
}
}

Do you really want to construct a new string every time the property is
accessed?

You've got no better choice for properties which are arrays, since the
arrays are mutable through the interface you return. This is one of the
reasons why it isn't recommended that you make properties which are
arrays, and use collections instead.

Yes, but in this example, the get method creates a new array every time
it is accessed instead of returning a reference to an existing private
field. I wasn't making any statement as to its suitability.

private string[,,] _foo;
public string[,,] Foo
{
get { return _foo;}
}

This assumes that somewhere else prior the array was created and filled
with the appropriate data. I agree that a collection or List<> would
be better.

Would you create a little helper class and then have a List<> of these?
That might be a better approach.
 
From one "old" C programmer to another, welcome to the C# fold.

The first question to clear out of the way is whether you are using
..NET (C#) 1.1 or 2.0. This will change the answers you get from some
people in this newsgroup, as some things can be done better / more
clearly in 2.0, while some solutions that work in 2.0 would have to be
reworked for 1.1.

I gave a quick read over your problem description. Forgive me if my
solution is off the mark in a few places: I have a bug I picked up on
vacation and my brain is a bit foggy today.

I'm hoping to give you a little object-oriented background here, and
suggest several solutions that involve varying levels of reworking your
application. Obviously, you don't want to do a whole ton of rework just
to shoehorn the thing into C#, but only you know how much is "too much"
rework, so I'll give you more background than precise code.

Even back when I worked in C, I tended to avoid arrays. I had two small
C source files that I hauled around with me from project to project: an
implementation of a doubly linked list, and an implementation of a hash
table. Over 20 years of programming, I found that 98% of "store stuff
in memory" problems boiled down to storing them in an expandable /
modifiable list, or storing them by key and retrieving them by key.

The problem with arrays is that they're fixed when they're created.
Now, "when they're created" is different in C and C#: in C you
(usually) declare an array and specify its size, and the array is
effectively "created" when the program loads.

In C#, you declare an array without specifying its limits:

double[,] weightAndBalance;

At this point, the variable weightAndBalance contains null: the same,
good ol' null that C had, a null pointer. At that same point, or later
in the program, you have to actually create an _instance_ of that
array, and at that point you say how big you want it:

weightAndBalance = new double[2,34];

You can combine these into one line if you already know, at the point
where you declare weightAndBalance, how big you want it to be:

double[,] weightAndBalance = new double[2,34];
From hereon in, the dimensions of the object to which weighAndBalance
refers ("points to" in C lingo) are fixed. However, you can always toss
that array and have weightAndBalance point to a new one:

weightAndBalance = new double[2,150];

at which point the previous array is fodder for the Garbage Collector
(GC).

Notice that in C an array is (generally speaking) created on the stack
or as part of a static program load, and you use the pointer only when
you need a pointer. In c#, you _always_ have a pointer, and the array
is created dynamically on the heap when you ask that it be created.

Notice also that you don't need to wrap the array in a class: you can
declare it as an array and just pass it around as an array, declaring
method (function) parameters as "double [,]". This isn't very nice,
because if you ever have to change the type, you have to fix it
everywhere. However, a two-dimensional array of doubles is a perfectly
respectable object and you can pass (references to) it around just as
you can for any other object.

Now in your case, it may be that there are always exactly 34 pairs of
numbers in the file. If that is true, you could use an array, but let's
look at two drawbacks of an array in this case, and I can show you two
ways of addressing those deficiencies in C#.

First, there's the case in which each of those 34 pairs of numbers
means something specific. So, it's not that you have 34 interchangeable
pairs of numbers, but that the first pair indicates the frobnitz
coordinates X and Y, the second pair indicates the foobar coordinates X
and Y, etc. This is the case in which the consciencious C programmer
would have made a struct of 34 pairs of doubles, and given each of the
34 (or 68) fields a name. You can do the same in C# with fields and
properties. In this case, your "array" becomes a class with 34 fields
and 34 corresponding properties, where each field returns a
System.Drawing.Point, or whatever corresponds to the meaning of those
value pairs.

Second, there's the case in which those 34 pairs of numbers really are
just captured data values, and the fact that an entry is the fifth
entry, for example, doesn't mean anything special. However, the number
of entires may change in the future. In the old days, I would have used
my custom "doubly-linked-list" .c functions, but C# comes with
ArrayList. You can index it like an array, but the advantage is that
you can add entries one by one:

ArrayList weightAndBalance = new ArrayList();
while reading file...
{
... read firstValue and secondValue from file line ...
System.Drawing.Point aPoint = new Point(firstValue, secondValue);
weightAndBalance.Add(aPoint);
}

Now you can query the number of entries using WeightAndBalance.Count,
and get at any entry using the usual [] notation.

As someone pointed out, though, any part of your program can update
this ArrayList (or array, if the size is fixed and you don't need an
ArrayList) if you return it from a property:

public ArrayList WeightAndBalanceData
{
get { return this._weightAndBalance; }
}

Remember, everything in C# is pointers, so by offering only a "get"
you're denying the caller the ability to change the pointer, but they
still have the power to change the contents of the array to which the
resulting pointer points.

If you have an existing app, you may not care about this: the
application itself may handle who can update what at a higher level.
However, object oriented programming does give you the power to control
this kind of access at the code level, so that the object itself
enforces rules about who can update the data. It all depends upon how
radically you want to reengineer the app you're working on.

Anyway, that's enough babbling for one post. Hope this helped.
 
Chris Dunaway said:
Yes, but in this example, the get method creates a new array every time
it is accessed instead of returning a reference to an existing private
field. I wasn't making any statement as to its suitability.

Sure. I was just making a general point about properties that return
arrays.

-- Barry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top