Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (9.26 MB, 1,017 trang )
CHAPTER 1 ■ APPLICATION DEVELOPMENT
public int DailyTemp
{
get;
set;
}
public int AveTempSoFar
{
get;
set;
}
}
public class WeatherForecast
{
private int[] temps = { 54, 63, 61, 55, 61, 63, 58 };
IList
{"Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "Sunday"};
public WeatherReport this[string dow]
{
get
{
// Get the day of the week index.
int dayindex = daysOfWeek.IndexOf(dow);
return new WeatherReport()
{
DayOfWeek = dayindex,
DailyTemp = temps[dayindex],
AveTempSoFar = calculateTempSoFar(dayindex)
};
}
set
{
temps[daysOfWeek.IndexOf(dow)] = value.DailyTemp;
}
}
private int calculateTempSoFar(int dayofweek)
{
int[] subset = new int[dayofweek + 1];
Array.Copy(temps, 0, subset, 0, dayofweek + 1);
return (int)subset.Average();
}
}
public class Recipe01_24
{
static void Main(string[] args)
{
49
CHAPTER 1 ■ APPLICATION DEVELOPMENT
// Create a new weather forecast.
WeatherForecast forecast = new WeatherForecast();
// Use the indexer to obtain forecast values and write them out.
string[] days = {"Monday", "Thursday", "Tuesday", "Saturday"};
foreach (string day in days)
{
WeatherReport report = forecast[day];
Console.WriteLine("Day: {0} DayIndex {1}, Temp: {2} Ave {3}", day,
report.DayOfWeek, report.DailyTemp, report.AveTempSoFar);
}
// Change one of the temperatures.
forecast["Tuesday"] = new WeatherReport()
{
DailyTemp = 34
};
// Repeat the loop.
Console.WriteLine("\nModified results...");
foreach (string day in days)
{
WeatherReport report = forecast[day];
Console.WriteLine("Day: {0} DayIndex {1}, Temp: {2} Ave {3}", day,
report.DayOfWeek, report.DailyTemp, report.AveTempSoFar);
}
Console.WriteLine("\nMain method complete. Press Enter.");
Console.ReadLine();
}
}
}
50
CHAPTER 1 ■ APPLICATION DEVELOPMENT
Running the program gives the following results:
Day: Monday DayIndex 0, Temp: 54 Ave 54
Day: Thursday DayIndex 3, Temp: 55 Ave 58
Day: Tuesday DayIndex 1, Temp: 63 Ave 58
Day: Saturday DayIndex 5, Temp: 63 Ave 59
Modified results...
Day: Monday DayIndex 0, Temp: 54 Ave 54
Day: Thursday DayIndex 3, Temp: 55 Ave 51
Day: Tuesday DayIndex 1, Temp: 34 Ave 44
Day: Saturday DayIndex 5, Temp: 63 Ave 54
Main method complete. Press Enter
51
CHAPTER 2
■■■
Data Manipulation
Most applications need to manipulate some form of data. The Microsoft .NET Framework provides
many techniques that simplify or improve the efficiency of common data manipulation tasks. The
recipes in this chapter describe how to do the following:
•
Manipulate the contents of strings efficiently to avoid the overhead of automatic
string creation due to the immutability of strings (recipe 2-1)
•
Represent basic data types using different encoding schemes or as byte arrays to
allow you to share data with external systems (recipes 2-2, 2-3, and 2-4)
•
Validate user input and manipulate string values using regular expressions
(recipes 2-5 and 2-6)
•
Create System.DateTime objects from string values, such as those that a user might
enter, and display DateTime objects as formatted strings (recipe 2-7)
•
Mathematically manipulate DateTime objects in order to compare dates or
add/subtract periods of time from a date (recipe 2-8)
•
Sort the contents of an array or an ArrayList collection (recipe 2-9)
•
Copy the contents of a collection to an array (recipe 2-10)
•
Use the standard generic collection classes to instantiate a strongly typed
collection (recipe 2-11)
•
Use generics to define your own general-purpose container or collection class that
will be strongly typed when it is used (recipe 2-12)
•
Serialize object state and persist it to a file (recipes 2-13 and 2-14)
•
Read user input from the Windows console (recipe 2-15)
•
Use large integer values (recipe 2-16)
•
Select elements from an array or collection (recipe 2-17)
•
Remove duplicate entries from an array or collection (recipe 2-18)
53
CHAPTER 2 ■ DATA MANIPULATION
2-1. Manipulate the Contents of a String Efficiently
Problem
You need to manipulate the contents of a String object and want to avoid the overhead of automatic
String creation caused by the immutability of String objects.
Solution
Use the System.Text.StringBuilder class to perform the manipulations and convert the result to a
String object using the StringBuilder.ToString method.
How It Works
String objects in .NET are immutable, meaning that once created their content cannot be changed. For
example, if you build a string by concatenating a number of characters or smaller strings, the Common
Language Runtime (CLR) will create a completely new String object whenever you add a new element to
the end of the existing string. This can result in significant overhead if your application performs
frequent string manipulation.
The StringBuilder class offers a solution by providing a character buffer and allowing you to
manipulate its contents without the runtime creating a new object as a result of every change. You can
create a new StringBuilder object that is empty or initialized with the content of an existing String
object. You can manipulate the content of the StringBuilder object using overloaded methods that
allow you to insert and append string representations of different data types. At any time, you can obtain
a String representation of the current content of the StringBuilder object by calling
StringBuilder.ToString.
Two important properties of StringBuilder control its behavior as you append new data: Capacity
and Length. Capacity represents the size of the StringBuilder buffer, and Length represents the length of
the buffer’s current content. If you append new data that results in the number of characters in the
StringBuilder object (Length) exceeding the capacity of the StringBuilder object (Capacity),
StringBuilder must allocate a new buffer to hold the data. The size of this new buffer is double the size
of the previous Capacity value. Used carelessly, this buffer reallocation can negate much of the benefit of
using StringBuilder. If you know the length of data you need to work with, or know an upper limit, you
can avoid unnecessary buffer reallocation by specifying the capacity at creation time or setting the
Capacity property manually. Note that 16 is the default Capacity property setting. When setting the
Capacity and Length properties, be aware of the following behavior:
•
•
54
If you set Capacity to a value less than the value of Length, the Capacity property
throws the exception System.ArgumentOutOfRangeException. The same exception is
also thrown if you try to raise the Capacity setting above the value of the
MaxCapacity property. This should not be a problem unless you want to allocate
more that 2 gigabytes (GB).
If you set Length to a value less than the length of the current content, the content
is truncated.
CHAPTER 2 ■ DATA MANIPULATION
•
If you set Length to a value greater than the length of the current content, the
buffer is padded with spaces to the specified length. Setting Length to a value
greater than Capacity automatically adjusts the Capacity value to be the same as
the new Length value.
The Code
The ReverseString method shown in the following example demonstrates the use of the StringBuilder
class to reverse a string. If you did not use the StringBuilder class to perform this operation, it would be
significantly more expensive in terms of resource utilization, especially as the input string is made
longer. The method creates a StringBuilder object of the correct capacity to ensure that no buffer
reallocation is required during the reversal operation.
using System;
using System.Text;
namespace Apress.VisualCSharpRecipes.Chapter02
{
class Recipe02_01
{
public static string ReverseString(string str)
{
// Make sure we have a reversible string.
if (str == null || str.Length <= 1)
{
return str;
}
// Create a StringBuilder object with the required capacity.
StringBuilder revStr = new StringBuilder(str.Length);
// Loop backward through the source string one character at a time and
// append each character to StringBuilder.
for (int count = str.Length - 1; count > -1; count--)
{
revStr.Append(str[count]);
}
// Return the reversed string.
return revStr.ToString();
}
public static void Main()
{
Console.WriteLine(ReverseString("Madam Im Adam"));
Console.WriteLine(ReverseString(
"The quick brown fox jumped over the lazy dog."));
55