Hi,
This is a general question on programming C# with Windows Forms and .NET.
I have to perform some mathematical operations on arrays, and in previous programming, C, Pascal, i used to use Procedures or Functions, and pass the array to the procedure/function, where as now i have specific global arrays.
To stop having to repeat code in each menu option code section to peform the mathematical function, i was going to use a single function called by each section of the code as and when required.
Is this still good practice, or should each menu selection from the window form have its own code ?. Seems and obvious answer to use a called procedure, just need to make sure, or, are there any other best practices ?.
Thanks in advance for your help.
Regards,
Richard.
Richard ShadboltPosted Oct 22, 2007, 2:11 PM
Hi Alan,
Thanks for the help. In the end through trial and error i was able to pass the array to another method in another class to do the necessary calculations etc.
I have approached this from programming in C using C# and windows Forms, so it is not the best way to have started. I am in the operation of converting most of the code to class based approach - which is not too bad - willl use the namespace to separate the classes and their methods to a more readable form - has made a difference already - had reams of code all under one windows form menu click.
I checked out the link that you provided and the book i downloaded is quite good - have a few Charles Petzold books on windows programming from the past. Programming is not my main work area at all, so i will not be able to read it in work time. Hence the reason why i keep on forgetting what i have learnt previously - not enough practice.
Again, thanks for your help, it is much appreciated.
Regards,
Richard.
AlanPosted Oct 21, 2007, 7:14 PM
Hi Richard,
Well, the first point to make is that arrays in C# are always reference types even if the element type itself (such as int) is a value type. This means that a variable or parameter of an array type contains a pointer to where the data is stored, not the actual data itself.
So, if you have this method declaration in your Global class:
public sealed class Global
{
private static int[,,] myArray;
public static int MyArray
{
get { return myArray;}
// private 'do nothing' constructor to prevent instantiation
private Global(){}
public static void SomeMethod (int[,,] someArray)
{
// do something with myArray and save it to the static field
myArray = someArray;
}
}
then the 3D array can be passed to the method, manipulated and saved to the static field, which we now expose to outside code through a read-only property.
As the Array is a reference type, the array object which is passed to the method will be changed because the method has a pointer to that array. So, there's no need to use 'ref' or 'out' which are mostly used for value type parameters. You can use them with reference types, which means that the method can not only change the state of the array but can even assign a different array object altogether to the parameter which is not usually a good thing.
So I'd stick to a static class to store and manipulate your global variables and, yes, all fields within the same static class can access each other whether they're declared public or private.
I'd suggest taking a look at this free online book from Charles Petzold which has been written for the C or C++ programmer who is moving over to C#:
http://www.charlespetzold.com/dotnet/
Richard ShadboltPosted Oct 21, 2007, 10:37 AM
Hi Alan,
I have been checking the C# book by Microsoft - VS and C#, and there is a section explaining how parameters are not changed, but when the integer is embedded in a class, you can change the value of that integer - which is what you have shown me in your code.
The reason for asking about this again, is that i am slowly converting my program to C# methodology and implementation. I wish to pass an array [55,200,2] to a method which will use this array in it's calculations, and store the results in the array in the class member (which is static, hence global)
In the book i have, the section then goes on to explain that you can use ref and out as ways of modifying members/parameters passed to it.
Hence, i am not certain on what to do. Do i use the static classes and members to create global variables, and can i pass other static class variables/memebers to another static class variable/member ?.
Or, is it better to use ref and out ?. Or is ref and out the only way to do this ?.
The MS book i have is a teaching book as you go along, and the Wrox book is like a reference book. What i am looking for is a book that essentially says - you programmed in C like this, to do it in C# these are the options, and discuss the pros and cons of each C# implementation. Is there such a book or faq i can examine ?. Thanks.
Regards,
Richard.
Richard ShadboltPosted Oct 19, 2007, 1:47 PM
Hi Alan,
Thanks for that piece of code.
The book i have is a Wrox book on VS2005, and i did not realise that my Visual Studio was for C# v1.1. I would have been there for hours trying to figure out what i was doing wrong.
I have the code working as required, which is really good, as i can try and convert the code already written to C++/C# style etc.
From what you have said, for a more appropriate programming style, i should be using methods on memebers etc, to achieve some of the calculations i need to complete.
Thanks again for your help on this, very much appreciated.
Regards,
Richard.
AlanPosted Oct 18, 2007, 7:00 AM
Hi Richard,
As you're using C# 1.1 (VS 2003), you won't be able to create a static class as such but you will be able to simulate one by creating a sealed class with a private constructor. Something like the following - for simplicity I've used a console rather than a winforms app and have exposed the array field (assumed to be of type int) directly rather than hide it with a property which is OK if you don't need to check values which are assigned to it.
Notice that, as the array field is static, it's automatically initialized by the system prior to its first use and so you don't need to create an instance of the Global class first (and can't do in any case as we've made the constructor private):
using System;
class Test
{
static void Main()
{
// initialize first column of MyArray to consecutive integers from zero
for (int i = 0; i < 2000; i++)
Global.MyArray[i,0] = i;
// print out value of 100th element in first column
Console.WriteLine(Global.MyArray[99, 0]);
Console.ReadLine();
}
}
public sealed class Global
{
// all elements set to zero by default
public static int[,] MyArray = new int[2000, 6];
// private 'do nothing' constructor to prevent instantiation
private Global(){}
// other code
}
Richard ShadboltPosted Oct 18, 2007, 5:34 AM
Alan,
Thanks for the reply. I had to look up some of the reference books i have to ensure i understood what you have written.
I am using Visual Studio 2003 .NET Professional, and have already created the application using Forms etc., but used C style programming since it is quicker for me to use - not much experience in C++ although i have been on courses.
I created a static class with a 2000 x 6 element array, using the new statement in the class definition. From what i can determine, this will not be created (instantiated ???), until i create a single instance of the class. Within Visual Studio, i have the main form, so do i create the instance of the class with the static member, (or static class if i rewrite the class code), in the main Form, or in the area where i have already created arrays etc., in the C style programming i have used (just below the new class i have created) ?. Thanks.
Regards,
Richard.
AlanPosted Oct 16, 2007, 10:50 AM
One of the major differences between C and C# is, of course, that the latter has no concept of global data or functions - everything has to be inside a class or struct.
However, globals can be simulated in C# by using a static class (i.e. a class which cannot be instantiated or inherited from and all of whose members are static) and sometimes this is the best design. The alternative is to define a singleton class (i.e. a class where only one instance can be created) though, personally, I prefer to use the simpler static class unless there is some compelling reason to do otherwise.
So, if you want your multi-dimensional arrays, and the methods to access or manipulate them, to be accessible to all your other code, then I'd be inclined to use a static class. Personally, I've never had any problems in maintaining these and, if the data is truly global, I don't see why you would need to change to an instance based approach at a later date.
Richard ShadboltPosted Oct 16, 2007, 9:53 AM
Alan,
Thanks for the reply.
I can understand that keeping the program to small modules makes the code easier to understand and maintain. I am working on multi-dimentsional arrays, with 2000 elements by 50 elements by 6 elements, as a general example.
Is it then better to create an object with the required array embedded in the class, with associated methods to clear the array ?. ( i think i have used the right terminology).
I am used to programming with C, and it's functions and procedures approach. I suppose i can use this method, but will the code be harder to maintain, and are there any problems with future programming of specific methods that require a class based approach /. Thanks.
Regards,
Richard.
AlanPosted Oct 15, 2007, 9:05 AM
Well, nowadays, rather than write monumental 'do everything' methods, it's generally recommended that you should write smaller methods which just do one thing and that those methods should simply call each other if they need to do subsidiary things or to otherwise share code.
Moreover, for preference, all the code for a given method should be visible without having to scroll the screen.
The rationale here is that this makes code easier to understand, less error prone and easier to maintain.
I think on the whole it's good advice though, of course, it's easier said than done :)