270 likes | 285 Views
Gain a comprehensive understanding of arrays, enums, and events in programming. Learn how to work with arrays, resize them, access their elements, and use enums and events effectively.
E N D
Arrays • Arrays are data structures consisting of related data items of the same type. • Arrays are fixed-length entities—they remain the same length once they are created. • Length property gives the length of the array. • static Array.Resizeresizes an array. It takes two arguments—the array to be resized and the new length. • Arrays are reference types—what we typically think of as an array is actually a reference to an array object. • If you pass an array parameter to a method, it is passed by reference. • The elements of an array can be either value types or reference types. • For example, every element of an int array is an int value, and every element of a string array is a reference to a string object. • We access an array element specifying array’s name and element’s index (position in the array). • Index starts at 0 (zero). • CLR performs bounds checking for you and throws IndexOutOfRangeException.
Examples • See Array.cs • int[] c = new int[12]; string[] c = new string[10]; • int[] c; c = new int[12]; • for (inti = 0; i < array.Length; i++) Console.WriteLine("{0} {1}", i, array[i]); • int[] array = {32, 27, 64, 18, 95, 14, 90, 70, 60, 37}; • const int ARRAY_LENGTH = 10; int[] array = new int[ARRAY_LENGTH]; for (inti = 0; i < array.Length; i++) array[i] = 2 + 2 * i; • Suppose you want to simulate rolling a six-sided die 6000 times. • RollDie.cs
foreach • The foreachstatement iterates through the elements of an entire array or collection. foreach (type identifierinarrayName ) { <statement1>; ... <statementN>; } • type and identifier are the type and name (e.g. int number) of the iteration variable. • The type of the iteration variable must match the type of the elements in the array. • The iteration variable represents successive values in the array on successive iterations of the foreach statement.
Example: foreach.cs int[] array = {87, 68, 94, 100, 83, 78, 85, 91, 76}; int total = 0; // add each element's value to total foreach ( int number in array ) total += number;
foreach • The foreach statement can be used with any collection .NET provides as long as the type implements the IEnumerable and IEnumerator interface. • In C#, it is not strictly necessary for a collection class to inherit from IEnumerable and IEnumerator in order to be compatible with foreach; as long as the class has the required GetEnumerator, MoveNext, Reset, and Current members, it will work with foreach. Omitting the interfaces has the advantage of allowing you to define the return type of Current to be more specific than object, thereby providing type-safety. • We will revisit collections later in the course. • Windows Forms has collections properties.
Implicitly Typed Variables • C# provides a new feature—called implicitly typed local variables—that enables the compiler to infer a local variable’s type based on the type of the variable’s initializer. • To distinguish such an initialization from a simple assignment statement, the var keyword is used in place of the variable’s type. • You can use local type inference with control variables in the header of a for or foreach statement. • if myArray is an array of ints, the following foreach statement headers are equivalent: foreach (int number in myArray) foreach (var number in myArray)
Passing Arrays as Parameters • To pass an array argument to a method, specify the name of the array without any brackets. For a method to receive an array reference through a method call, the method’s parameter list must specify an array parameter. • When an argument to a method is an entire array or an individual array element of a reference type, the called method receives a copy of the reference. • When an argument to a method is an individual array element of a value type, the called method receives a copy of the element’s value. • To pass an individual array element to a method, use the indexed name of the array as an argument in the method call. • Example: ArrayReferenceTest.cs
Multidimensional Arrays • 2-dimensional rectangular array: • An array with m rows and n columns is called an m-by-narray. • Every element in array a is identified by an array-access expression of the form a[ row,column ]; • A two-by-two rectangular array b can be declared and initialized as follows: int[ , ] b = { { 1, 2 }, { 3, 4 } }; • The initializer values are grouped by row in braces.
Jagged Arrays • A jagged array is a one-dimensional array whose elements are one-dimensional arrays. • The lengths of the rows in the array need not be the same. • A jagged array with three rows of different lengths could be declared and initialized as follows: int[][] jagged = { new int[] { 1, 2 }, new int[] { 3 }, new int[] { 4, 5, 6 } };
Multidimensional Arrays • A rectangular array can be created with an array-creation expression: int[ , ] b; b = new int[ 3, 4 ]; • A jagged array cannot be completely created with a single array-creation expression. Each one-dimensional array must be initialized separately. • A jagged array can be created as follows: int[][] c; c = new int[ 2 ][ ]; // create 2 rows c[ 0 ] = new int[ 5 ]; // create 5 columns for row 0 c[ 1 ] = new int[ 3 ]; // create 3 columns for row 1
Variable-length argument lists • Variable-length argument lists allow you to create methods that receive an arbitrary number of arguments. • The necessary params modifier can occur only in the last entry of the parameter list. • Example: Params.cs
Command-line Arguments • You can pass command-line argumentsto an application by including a parameter of type string[] in the parameter list of Main. • By convention, this parameter is named args. • The execution environment passes the command-line arguments as an array to the application’s Main method. • The number of arguments passed from the command line is obtained by accessing the array’s Length property. • Command-line arguments are separated by white space, not commas. • Example: VarargsTest.cs
Indexers • A class that encapsulates lists of data can use keyword this to define property-like class members called indexers that allow array-style indexed access to lists of elements. • You can define both integer indices and noninteger indices. • Indexers can return any type, even one that is different from the type of the underlying data. • Unlike properties, for which you can choose an appropriate property name, indexers must be defined with keyword this.
Indexers (Example: IndexersTest) • Indexers have the general form: accessModifierreturnType this[ IndexType1 name1, IndexType2 name2,…]{ get {// use name1, name2, ... indices here to get data } set {// use name1, name2, ... indices here to set data }} • The IndexType parameters are accessible to the get and set accessors. • The indexer’s get accessor must return a value of type returnType. • As in properties, the set accessor can use the implicit parameter value to reference the value that should be assigned to the element.
enum • An enumerated type is a value type that defines a set of symbolic name and value pairs. • For example: enum type identifying a single color: public enum Color { White, // Assigned a value of 0 Red, // Assigned a value of 1 Green, // Assigned a value of 2 Blue, // Assigned a value of 3 Orange, // Assigned a value of 4 } • Other examples: days/months, cards types, states in a game, etc. etc. • Let’s see example code: enum.cs
System.Enum methods • public static bool IsDefined(Type enumType, object value); • public static object Parse(Type enumType, string value); • public static object Parse(Type enumType, string value, bool ignoreCase); • public static string GetName(Type enumType, object value); • public static string[] GetNames(Type enumType); • public static Array GetValues(Type enumType); • public int CompareTo(object target); • public static string Format(Type enumType, object value, string format); • public override string ToString(); • public static object ToObject(Type enumType, int value); // many overloads
Events • An event notifies other objects that something special has happened • Example: Button class offers a Click event • Example: An e-mail application receives new e-mails. When a new e-mail arrives, user wants to be notified via message box or forward that e-mail to his fax machine or mobile phone. Fax Machine Mobile Phone 3) Notify that new mail arrived 1) register for notification 1) register for notification MailManager 2) new mail arrives
Step #1: Define a type that will hold any additional information that should be sent to receivers of the event notification • When an event is raised, the object raising the event might want to pass some additional information to the objects receiving the event notification • This additional information needs to be encapsulated in its own class derived from System.EventArgs • See NewMailEventArgs(MailManager.cpp)
Step #2: Define the event member • An event member is defined using the event keyword public eventEventHandler<EventArgs> name_event; publiceventEventHandler<NewMailEventArgs>NewMail; • The type of the event is EventHandler<NewMailEventArgs> • This means event receivers are supposed to implement and pass a function delegate with following signature: void MethodName(Object sender, NewMailEventArgs e); • System.EventHandleris defined as: public delegate void EventHandler<TEventArgs> (Object sender, TEventArgs e);
Step #3: Receiver Objects Implement the EventHandler method • A method that performs a task in response to an event is called an event handler. • Event member in previous step defined what type of event handler it expects. • This means event receivers are supposed to implement and pass a function delegate with following signature: void MethodName(Object sender, NewMailEventArgs e); • See Fax and Pager in MailManager.cpp • When the event is raised Fax::FaxMsg and Pager::SendMsgToPagermethods are called
Step #4: Receiver Objects Registers for the Event • The objects interested in receiving notification when the event happens, should add their event handler to the event • See Fax and Pager constructor in MailManager.cpp public Fax(MailManager mm) { // Construct an instance of the EventHandler<NewMailEventArgs> // delegate that refers to our FaxMsg callback method. // Register our callback with MailManager's NewMail event mm.NewMail += FaxMsg; }
Step #5: Define a method responsible for raising the event to notify registered objects that the event has occurred • The class should define a protected method to be called internally when the event is to be raised. • This method takes one parameter, NewMailEventArgs object, to include the information to be passed to the receivers of the event notification. • If the event, NewMailis not null, the event will be raised by simply calling the event as a method. • See OnNewMail in MailManager.cpp protected void OnNewMail(NewMailEventArgs e) { EventHandler<NewMailEventArgs> temp = NewMail; if (temp != null) temp(this, e); }
Step #6: Define a method that translates the input into the desired event • The class will usually take some input and translate it to the way the event wants. • We could join Step#5 (OnNewMail) and #6 (SimulateNewMail)depending on implementation. • See SimulateNewMail in MailManager.cpp public void SimulateNewMail( String from, String to, String subject) { NewMailEventArgs e = new NewMailEventArgs( from, to, subject); OnNewMail(e); }
Step #7: Receiver Objects De-Registers themselves from the Event • When the objects interested in receiving notification are done with listening the event or do not want to listen to the event anymore, should remove their event handler from the event • See Fax and Pager in Unregisterin MailManager.cpp // This method should be executed to have the Fax object unregister // itself with the NewMail event so that it no longer receives // notifications public void Unregister(MailManager mm) { // Unregister ourself with MailManager's NewMail event mm.NewMail -= FaxMsg; }
User Interface and Events • GUI (Graphical User Interface)’s are event driven. • When the user interacts with a GUI component, the event drives the program to perform a task. • Enter key is pressed • Mouse double clicked • Mouse moves to an area • The GUI controls, which are .NET classes, are like MailManager: they raise several events and send notifications to receivers. • Your class just needs to register to these events and hence implement the event handler methods. • We will see many examples in Windows Forms.