Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Visual CSharp 2005 Recipes (2006) [eng]

.pdf
Скачиваний:
48
Добавлен:
16.08.2013
Размер:
4.04 Mб
Скачать

48 C H A P T E R 2 D ATA M A N I P U L AT I O N

The Code

The following example demonstrates the flexibility of the Parse method and the use of the ParseExact method. Refer to the documentation for the System.Globalization.DateTimeFormatInfo class in the

.NET Framework SDK document for complete details on all available format specifiers.

using System;

namespace Apress.VisualCSharpRecipes.Chapter02

{

class Recipe02_07

{

public static void Main(string[] args)

{

// 1st September 2005 00:00:00

DateTime dt1 = DateTime.Parse("Sep 2005");

// 5th September 2005 14:15:33

DateTime dt2 = DateTime.Parse("Monday 5 September 2005 14:15:33");

// 5th September 2005 00:00:00

DateTime dt3 = DateTime.Parse("5,9,05");

// 5th September 2005 14:15:33

DateTime dt4 = DateTime.Parse("5/9/2005 14:15:33");

// Current Date 14:15:00

DateTime dt5 = DateTime.Parse("2:15 PM");

//Display the converted DateTime objects. Console.WriteLine(dt1); Console.WriteLine(dt2); Console.WriteLine(dt3); Console.WriteLine(dt4); Console.WriteLine(dt5);

//Parse only strings containing LongTimePattern.

DateTime dt6 = DateTime.ParseExact("2:13:30 PM", "h:mm:ss tt", null);

//Parse only strings containing RFC1123Pattern. DateTime dt7 = DateTime.ParseExact(

"Mon, 05 Sep 2005 14:13:30 GMT",

"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'", null);

//Parse only strings containing MonthDayPattern.

DateTime dt8 = DateTime.ParseExact("September 05", "MMMM dd", null);

//Display the converted DateTime objects. Console.WriteLine(dt6); Console.WriteLine(dt7); Console.WriteLine(dt8);

//Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter"); Console.ReadLine();

}

}

}

C H A P T E R 2 D ATA M A N I P U L AT I O N

49

2-8. Add, Subtract, and Compare Dates and Times

Problem

You need to perform basic arithmetic operations or comparisons using dates and times.

Solution

Use the DateTime and TimeSpan structures, which support standard arithmetic and comparison operators.

How It Works

A DateTime instance represents a specific time (such as 4:15 a.m. on September 5, 1970), whereas

a TimeSpan instance represents a period of time (such as 2 hours, 35 minutes). You may want to add, subtract, and compare TimeSpan and DateTime instances.

Internally, both DateTime and TimeSpan use ticks to represent time. A tick is equal to 100 nanoseconds. TimeSpan stores its time interval as the number of ticks equal to that interval, and DateTime stores time as the number of ticks since 12:00:00 midnight on January 1 in 0001 C.E. (C.E. stands for Common Era and is equivalent to A.D. in the Gregorian calendar.) This approach and the use of operator overloading makes it easy for DateTime and TimeSpan to support basic arithmetic and comparison operations. Table 2-4 summarizes the operator support provided by the DateTime and TimeSpan structures.

Table 2-4. Operators Supported by DateTime and TimeSpan

Operator

TimeSpan

DateTime

Assignment (=)

Because TimeSpan is a structure,

Because DateTime is

 

assignment returns a copy and

a structure, assignment

 

not a reference

returns a copy and not

 

 

a reference

Addition (+)

Adds two TimeSpan instances

Adds a TimeSpan instance to

 

 

a DateTime instance

Subtraction (-)

Subtracts one TimeSpan instance

 

from another TimeSpan instance

Equality (==)

Compares two TimeSpan

 

instances and returns true if

 

they are equal

Inequality (!=)

Compares two TimeSpan

 

instances and returns true if

 

they are not equal

Greater than (>)

Determines if one TimeSpan

 

instance is greater than another

 

TimeSpan instance

Greater than or equal to (>=)

Determines if one TimeSpan

 

instance is greater than or equal

 

to another TimeSpan instance

Subtracts a TimeSpan instance or a DateTime instance from a DateTime instance

Compares two DateTime instances and returns true if they are equal

Compares two DateTime instances and returns true if they are not equal

Determines if one DateTime instance is greater than another DateTime instance

Determines if one DateTime instance is greater than or equal to another DateTime instance

(Continued)

50 C H A P T E R 2 D ATA M A N I P U L AT I O N

Table 2-4. Continued

Operator

TimeSpan

DateTime

Less than (<)

Determines if one TimeSpan

Determines if one DateTime

 

instance is less than another

instance is less than another

 

TimeSpan instance

DateTime instance

Less than or equal to (<=)

Determines if one TimeSpan

Determines if one DateTime

 

instance is less than or equal

instance is less than or equal

 

to another TimeSpan instance

to another DateTime instance

Unary negation (-)

Returns a TimeSpan instance with

Not supported

 

a negated value of the specified

 

 

TimeSpan instance

 

Unary plus (+)

Returns the TimeSpan

Not supported

 

instance specified

 

 

 

 

The DateTime structure also implements the AddTicks, AddMilliseconds, AddSeconds, AddMinutes,

AddHours, AddDays, AddMonths, and AddYears methods. Each of these methods allows you to add (or subtract using negative values) the appropriate element of time to a DateTime instance. These methods and the operators listed in Table 2-4 do not modify the original DateTime; instead, they create a new instance with the modified value.

The Code

The following example demonstrates the use of operators to manipulate the DateTime and TimeSpan structures.

using System;

namespace Apress.VisualCSharpRecipes.Chapter02

{

class Recipe02_08

{

public static void Main()

{

//Create a TimeSpan representing 2.5 days. TimeSpan timespan1 = new TimeSpan(2, 12, 0, 0);

//Create a TimeSpan representing 4.5 days. TimeSpan timespan2 = new TimeSpan(4, 12, 0, 0);

//Create a TimeSpan representing 1 week. TimeSpan oneWeek = timespan1 + timespan2;

//Create a DateTime with the current date and time. DateTime now = DateTime.Now;

//Create a DateTime representing 1 week ago. DateTime past = now - oneWeek;

//Create a DateTime representing 1 week in the future. DateTime future = now + oneWeek;

//Display the DateTime instances.

Console.WriteLine("Now

:

{0}", now);

Console.WriteLine("Past

:

{0}",

past);

Console.WriteLine("Future:

{0}",

future);

C H A P T E R 2 D ATA M A N I P U L AT I O N

51

// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter"); Console.ReadLine();

}

}

}

2-9. Sort an Array or an ArrayList

Problem

You need to sort the elements contained in an array or an ArrayList structure.

Solution

Use the ArrayList.Sort method to sort ArrayList objects and the static Array.Sort method to sort arrays.

How It Works

The simplest Sort method overload sorts the objects contained in an array or ArrayList structure as long as the objects implement the System.IComparable interface and are of the same type. All of the basic data types implement IComparable. To sort objects that do not implement IComparable, you must pass the Sort method to an object that implements the System.Collections.IComparer interface. The IComparer implementation must be capable of comparing the objects contained within the array or ArrayList. (Recipe 13-3 describes how to implement both comparable types.)

The Code

The following example demonstrates how to use the Sort methods of the ArrayList and Array classes.

using System;

using System.Collections;

namespace Apress.VisualCSharpRecipes.Chapter02

{

class Recipe02_09

{

public static void Main()

{

//Create a new array and populate it. int[] array = { 4, 2, 9, 3 };

//Sort the array.

Array.Sort(array);

//Display the contents of the sorted array. foreach (int i in array) { Console.WriteLine(i); }

//Create a new ArrayList and populate it. ArrayList list = new ArrayList(4); list.Add("Michael");

list.Add("Kate");

list.Add("Andrea");

list.Add("Angus");

52C H A P T E R 2 D ATA M A N I P U L AT I O N

//Sort the ArrayList. list.Sort();

//Display the contents of the sorted ArrayList. foreach (string s in list) { Console.WriteLine(s); }

//Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter"); Console.ReadLine();

}

}

}

2-10. Copy a Collection to an Array

Problem

You need to copy the contents of a collection to an array.

Solution

Use the ICollection.CopyTo method implemented by all collection classes, or use the ToArray method implemented by the ArrayList, Stack, and Queue collections.

How It Works

The ICollection.CopyTo method and the ToArray method perform roughly the same function: they perform a shallow copy of the elements contained in a collection to an array. The key difference is that CopyTo copies the collection’s elements to an existing array, whereas ToArray creates a new array before copying the collection’s elements into it.

The CopyTo method takes two arguments: an array and an index. The array is the target of the copy operation and must be of a type appropriate to handle the elements of the collection. If the types do not match, or no implicit conversion is possible from the collection element’s type to the array element’s type, a System.InvalidCastException exception is thrown. The index is the starting element of the array where the collection’s elements will be copied. If the index is equal to or greater than the length of the array, or the number of collection elements exceeds the capacity of the array,

a System.ArgumentException exception is thrown.

The ArrayList, Stack, and Queue classes and their generic versions also implement the ToArray method, which automatically creates an array of the correct size to accommodate a copy of all the elements of the collection. If you call ToArray with no arguments, it returns an object[] array, regardless of the type of objects contained in the collection. For convenience, the ArrayList.ToArray method has an overload to which you can pass a System.Type object that specifies the type of array that the ToArray method should create. (You must still cast the returned strongly typed array to the correct type.) The layout of the array’s contents depends on which collection class you are using. For example, an array produced from a Stack object will be inverted compared to the array generated by an ArrayList object.

The Code

This example demonstrates how to copy the contents of an ArrayList structure to an array using the CopyTo method, and then shows how to use the ToArray method on the ArrayList object.

C H A P T E R 2 D ATA M A N I P U L AT I O N

53

using System;

using System.Collections;

namespace Apress.VisualCSharpRecipes.Chapter02

{

class Recipe02_10

{

public static void Main()

{

//Create a new ArrayList and populate it. ArrayList list = new ArrayList(5); list.Add("Brenda");

list.Add("George");

list.Add("Justin");

list.Add("Shaun");

list.Add("Meaghan");

//Create a string array and use the ICollection.CopyTo method

//to copy the contents of the ArrayList.

string[] array1 = new string[list.Count]; list.CopyTo(array1, 0);

//Use ArrayList.ToArray to create an object array from the

//contents of the collection.

object[] array2 = list.ToArray();

//Use ArrayList.ToArray to create a strongly typed string

//array from the contents of the collection.

string[] array3 = (string[])list.ToArray(typeof(String));

// Display the contents of the 3 arrays. Console.WriteLine("Array 1:");

foreach (string s in array1)

{

Console.WriteLine("\t{0}",s);

}

Console.WriteLine("Array 2:"); foreach (string s in array2)

{

Console.WriteLine("\t{0}", s);

}

Console.WriteLine("Array 3:"); foreach (string s in array3)

{

Console.WriteLine("\t{0}", s);

}

// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter"); Console.ReadLine();

}

}

}

54 C H A P T E R 2 D ATA M A N I P U L AT I O N

2-11. Use a Strongly Typed Collection

Problem

You need a collection that works with elements of a specific type so that you do not need to work with System.Object references in your code.

Solution

Use the appropriate collection class from the System.Collections.Generic namespace. When you instantiate the collection, specify the type of object the collection should contain using the generics syntax built into C# 2.0.

How It Works

The generics functionality added to .NET Framework 2.0 and supported by specific syntax in C# 2.0 make it easy to create type-safe collections and containers (see recipe 2-12). To meet the most common requirements for collection classes, the System.Collections.Generic namespace contains a number of predefined generic collections, including the following:

Dictionary

LinkedList

List

Queue

Stack

When you instantiate one of these collections, you specify the type of object that the collection will contain by including the type name in angled brackets after the collection name; for example, Dictionary<System.Reflection.AssemblyName>. As a result, all members that add objects to the collection expect the objects to be of the specified type, and all members that return objects from the collection will return object references of the specified type. Using strongly typed collections and working directly with objects of the desired type simplifies development and reduces the errors that can occur when working with general Object references and casting them to the desired type.

The Code

The following example demonstrates the use of generic collections to create a variety of collections specifically for the management of AssemblyName objects. Notice that you never need to cast to or from the Object type.

using System;

using System.Reflection;

using System.Collections.Generic;

namespace Apress.VisualCSharpRecipes.Chapter02

{

class Recipe02_11

{

public static void Main(string[] args)

{

// Create an AssemblyName object for use during the example. AssemblyName assembly1 = new AssemblyName("com.microsoft.crypto, " +

"Culture=en, PublicKeyToken=a5d015c7d5a0b012, Version=1.0.0.0");

C H A P T E R 2 D ATA M A N I P U L AT I O N

55

// Create and use a Dictionary of AssemblyName objects. Dictionary<string,AssemblyName> assemblyDictionary =

new Dictionary<string,AssemblyName>();

assemblyDictionary.Add("Crypto", assembly1);

AssemblyName ass1 = assemblyDictionary["Crypto"];

Console.WriteLine("Got AssemblyName from dictionary: {0}", ass1);

// Create and use a List of Assembly Name objects. List<AssemblyName> assemblyList = new List<AssemblyName>();

assemblyList.Add(assembly1);

AssemblyName ass2 = assemblyList[0];

Console.WriteLine("\nFound AssemblyName in list: {0}", ass1);

// Create and use a Stack of Assembly Name objects Stack<AssemblyName> assemblyStack = new Stack<AssemblyName>();

assemblyStack.Push(assembly1);

AssemblyName ass3 = assemblyStack.Pop();

Console.WriteLine("\nPopped AssemblyName from stack: {0}", ass1);

// Wait to continue.

Console.WriteLine("\nMain method complete. Press Enter"); Console.ReadLine();

}

}

}

2-12. Create a Generic Type

Problem

You need to create a new general-purpose type such as a collection or container that supports strong typing of the elements it contains.

Solution

Use the generics functionality added to .NET Framework 2.0. Define your class using the generics syntax provided in C# 2.0.

How It Works

You can leverage the generics capabilities of .NET Framework 2.0 in any class you define. This allows you to create general-purpose classes that can be used as type-safe instances by other programmers. When you declare your type, you identify it as a generic type by following the type name with a pair of angled brackets that contain a list of identifiers for the types used in the class. Here is an example:

56 C H A P T E R 2 D ATA M A N I P U L AT I O N

public class MyGenericType<T1, T2, T3>

This declaration specifies a new class named MyGenericType, which uses three generic types in its implementation (T1, T2, and T3). When implementing the type, you substitute the generic type names into the code instead of using specific type names. For example, one method might take an argument of type T1 and return a result of type T2, as shown here:

public T2 MyGenericMethod(T1 arg)

When other people use your class and create an instance of it, they specify the actual types to use as part of the instantiation. Here is an example:

MyGenericType<string,Stream,string> obj = new MyGenericType<string,Stream,string>();

The types specified replace T1, T2, and T3 throughout the implementation, so with this instance, MyGenericMethod would actually be interpreted as follows:

public Stream MyGenericMethod(string arg)

You can also include constraints as part of your generic type definition. This allows you to make specifications such as the following:

Only value types or only reference types can be used with the generic type.

Only types that implement a default (empty) constructor can be used with the generic type.

Only types that implement a specific interface can be used with the generic type.

Only types that inherit from a specific base class can be used with the generic type.

One generic type must be the same as another generic type (for example, T1 must be the same as T3).

For example, to specify that T1 must implement the System.IDisposable interface and provide a default constructor, that T2 must be or derive from the System.IO.Stream class, and that T3 must be the same type as T1, change the definition of MyGenericType as follows:

public class MyGenericType<T1, T2, T3> where T1 : System.IDisposable, new() where T2 : System.IO.Stream

where T3 : T1

{ \* ...Implementation... *\ }

The Code

The following example demonstrates a simplified bag implementation that returns those objects put into it at random. A bag is a data structure that can contain zero or more items, including duplicates of items, but does not guarantee any ordering of the items it contains.

using System;

using System.Collections.Generic;

namespace Apress.VisualCSharpRecipes.Chapter02

{

public class Bag<T>

{

//A list to hold the bag's contents. The list must be

//of the same type as the bag.

private List<T> items = new List<T>();

C H A P T E R 2 D ATA M A N I P U L AT I O N

57

//A method to add an item to the bag. public void Add(T item)

{

items.Add(item);

}

//A method to get a random item from the bag. public T Remove()

{

T item = default(T);

if (items.Count != 0)

{

//Determine which item to remove from the bag. Random r = new Random();

int num = r.Next(0, items.Count);

//Remove the item

item = items[num]; items.RemoveAt(num);

}

return item;

}

//A method to remove all items from the bag and return them

//as an array.

public T[] RemoveAll()

{

T[] i = items.ToArray(); items.Clear();

return i;

}

}

public class Recipe02_12

{

public static void Main(string[] args)

{

//Create a new bag of strings. Bag<string> bag = new Bag<string>();

//Add strings to the bag. bag.Add("Darryl"); bag.Add("Bodders"); bag.Add("Gary"); bag.Add("Mike"); bag.Add("Nigel"); bag.Add("Ian");

//Take four strings from the bag and display. Console.WriteLine("Item 1 = {0}", bag.Remove()); Console.WriteLine("Item 2 = {0}", bag.Remove()); Console.WriteLine("Item 3 = {0}", bag.Remove()); Console.WriteLine("Item 4 = {0}", bag.Remove());

Соседние файлы в предмете Программирование на C++