C# 2005 Programmer’s Reference - chapter 3 ppsx

66 354 0
C# 2005 Programmer’s Reference - chapter 3 ppsx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

ptg 52 CHAPTER 3 General Coding using System; using WpfControls = System.Windows.Controls; using AcmeControls = Acme.Widgets.Controls; namespace MyProgramNamespace { class MyClass { void DoSomething() { WpfControls.Button button = new WpfControls.Button(); AcmeControls.Dial dial = new AcmeControls.Dial(); } } } The keyword using is also used in the context of the Dispose Pattern (see Chapter 22, “Memory Management”). NOTE Use the Conditional Operator (?:) Scenario/Problem: You want to choose between two alternate values within a single statement. Solution: Use the conditional operator, sometimes called the ternary operator (for its three arguments). For example, (condition?a:b) is shorthand for if (condi- tion) { do a } else {do b}. class Program { static void Main(string[] args) { bool condition = true; int x = condition ? 13 : 14; Console.WriteLine(“x is {0}”, x); //you can also embed the condition in other statements Console.WriteLine(“Condition is {0}”, condition ? “TRUE” : “FALSE”); From the Library of Skyla Walker ptg 53 Use the Null-Coalescing Operator (??) } } This program prints the following output: x is 13 Condition is TRUE This operator is not limited to just assignments. You can also use it in situa- tions like this: bool actionSucceeded = CheckIfActionSucceeded(); actionSucceeded ? ReportSucceeded() : ReportFailed(); NOTE Use the Null-Coalescing Operator (??) Scenario/Problem: You want to simplify checking for null values. This is a common situation, where you need to check for a null value before you use a variable. Solution: The null-coalescing operator can simplify the syntax a bit. int? n = null; object obj = “Hello”; int x = 13; //short for if (n!=null) o = n; else o = -1; int? o = n ?? -1; object obj2 = obj ?? “ok”; //doesn’t make sense since x can’t be null //int y = x ?? -1; Console.WriteLine(“o = {0}”, o); Console.WriteLine(“obj2 = {0}”, obj2); The output is as follows: o = -1 obj2 = Hello From the Library of Skyla Walker ptg 54 CHAPTER 3 General Coding Add Methods to Existing Types with Extension Methods Scenario/Problem: You want to add a method to an existing type (for which you cannot change the source code) so that the syntax you use is existingType.MyNewMethod(). Solution: Create an extension method using special syntax, as in this example: //extension methods must be defined in a static class static class IntMethods { //extension methods must be static //the this keyword tells C# that this is an extension method public static bool IsPrime(this int number) { //check for evenness if (number % 2 == 0) { if (number == 2) return true; return false; } //don’t need to check past the square root int max = (int)Math.Sqrt(number); for (int i = 3; i <= max; i += 2) { if ((number % i) == 0) { return false; } } return true; } } class Program { static void Main(string[] args) { for (int i = 0; i < 100; ++i) { if (i.IsPrime()) From the Library of Skyla Walker ptg 55 Call Methods with Default Parameters { Console.WriteLine(i); } } Console.ReadKey(); } } A lot of extension methods are defined for you already (mostly for use in LINQ). Figure 3.3 shows how Visual Studio marks extension methods graphically. FIGURE 3.3 Visual Studio marks extension methods in IntelliSense with a down arrow to make them easy to identify. In this figure, Aggregate, All, Any, etc. are extension methods that operate on IEnumerable<T> types. Call Methods with Default Parameters Like operator overloading (See Chapter 2, “Creating Versatile Types”), you should be careful about defining extension methods because they pollute the name- space for all variables of that type. NOTE Scenario/Problem: You want to avoid creating many overloads of a method by specifying default values for some parameters. Solution: Use the new syntax in C# 4.0 to specify parameters with default values. class Program { static void Main(string[] args) From the Library of Skyla Walker ptg 56 CHAPTER 3 General Coding { ShowFolders(); ShowFolders(@”C:\”); //no, you can’t do this //ShowFolders(false); } static void ShowFolders(string root = @”C:\”, bool showFullPath = false) { foreach (string folder in Directory.EnumerateDirectories(root)) { string output = showFullPath ? folder : Path.GetFileName(folder); Console.WriteLine(output); } } //not allowed: default parameters must appear after //all non-default parameters //static void ShowFolders(string root = @”C:\”, bool showFullPath ) //{ //} } Default parameter usage can be a contentious issue. Personally, I’d rather have more overloads than use default parameters, but the feature is now here if you want it. Make sure you don’t hurt readability and maintainability with its usage. NOTE Call Methods with Named Parameters Scenario/Problem: You want to be able to call methods with named parame- ters, possibly to interface with dynamic languages. Solution: Use the new syntax in C# 4.0 to call methods with named parameters. Let’s use the same method from the previous section: //order doesn’t matter when they’re named ShowFolders(showFullPath: false, root: @”C:\Windows”); From the Library of Skyla Walker ptg 57 Defer Evaluation of a Value Until Referenced Defer Evaluation of a Value Until Referenced Scenario/Problem: You want to defer creation of a complex value until and unless it’s needed. Solution: Use the simple helper class Lazy<T> to wrap the value creation and pass it around as needed. Once the value is created, it is stored so that subse- quent accesses use the already created value. class Program { static void Main(string[] args) { Lazy<ICollection<string>> processes = new Lazy<ICollection<string>>( //anonymous delegate to do the creation of //the value, when needed () => { List<string> processNames = new List<string>(); foreach (var p in Process.GetProcesses()) { processNames.Add(p.ProcessName); } return processNames; }); PrintSystemInfo(processes, true); Console.ReadKey(); } static void PrintSystemInfo(Lazy<ICollection<string>> processNames, bool showProcesses) { Console.WriteLine(“MachineName: {0}”, Environment.MachineName); Console.WriteLine(“OS version: {0}”, Environment.OSVersion); Console.WriteLine(“DBG: Is process list created? {0}”, processNames.IsValueCreated); if (showProcesses) { Console.WriteLine(“Processes:”); foreach (string p in processNames.Value) { From the Library of Skyla Walker ptg 58 CHAPTER 3 General Coding Console.WriteLine(p); } } Console.WriteLine(“DBG: Is process list created? {0}”, processNames.IsValueCreated); } } The output is similar to the following: MachineName: BEN-DESKTOP OS version: Microsoft Windows NT 6.1.7100.0 DBG: Is process list created? False Processes: conhost explorer svchost svchost iexplore Idle many more DBG: Is process list created? True Enforce Code Contracts Scenario/Problem: You want methods that obey rules you specify, including invariants that must be obeyed at the beginning and end of method calls. Solution: Use the Contract class to add constraints to your methods. class Program { static void Main(string[] args) { List<int> list = new List<int>(); AppendNumber(list, 13); AppendNumber(list, -1); Console.ReadKey(); } From the Library of Skyla Walker ptg 59 Enforce Code Contracts static void AppendNumber(List<int> list, int newNumber) { Contract.Requires(newNumber > 0, “Failed contract: negative”); Contract.Ensures(list.Count == ➥ Contract.OldValue(list.Count) + 1); list.Add(newNumber); } } At first glance, these look like assertions—when you are running a debug build, they are. However, they do much more: . When used with an external tool (called a binary rewriter), they inject code to verify the contract is obeyed, including possibly at the end of methods when needed. . Emit metadata about the constraint that can then be analyzed by static code analysis tools. . When run in debug mode, they throw exceptions when contracts are violated. At the time of this writing, using Code Contracts required an extra download from Microsoft (go to http://research.microsoft.com/en-us/projects/contracts/). Once installed, Code Contracts will add a new tab in your project settings (see Figure 3.4). FIGURE 3.4 Code Contracts adds some new configuration settings to Visual Studio. From the Library of Skyla Walker ptg 60 CHAPTER 3 General Coding With the Visual Studio Team System version, you can also have a static checker that evaluates your code as you write it and notifies you of problems immediately (see Figure 3.5). FIGURE 3.5 The static checker integrates with Visual Studio Team System to interactively notify you of contract violations in your code. Implement Contracts on Interfaces Scenario/Problem: You want to implement contracts on every class that imple- ments an interface. Think of this as extending the requirements of an interface even deeper then the method declaration, by requiring not just the method signature, but also some level of expected behavior, even without a particular implementation. Solution: Because interfaces don’t have method bodies, you need to create a surrogate implementation of the interface and add the contracts there. You tie them together using attributes. [ContractClass(typeof(AddContract))] interface IAdd { UInt32 Add(UInt32 a, UInt32 b); } From the Library of Skyla Walker ptg 61 Enforce Code Contracts [ContractClassFor(typeof(IAdd))] class AddContract : IAdd { //private and explicit interface implementation UInt32 IAdd.Add(UInt32 a, UInt32 b) { Contract.Requires((UInt64)a + (UInt64)b < UInt32.MaxValue); return a+b; } } //this class does not need to specify the contracts class BetterAdd : IAdd { public UInt32 Add(UInt32 a, UInt32 b) { return a + b; } } void SomeFunc() { BetterAdd ba; //this will cause a contract exception ba.Add(UInt32.MaxValue, UInt32.MaxValue); } From the Library of Skyla Walker [...]... numberToParse = ➥” 234 7 436 5 237 84 230 457 834 795567 934 98547 534 68479567 230 9 ➥48 235 987 439 0”; BigInteger bi = BigInteger.Parse(numberToParse); Console.WriteLine(“N0: {0:N0}”, bi); Console.WriteLine(“R: {0:R}”, bi); Output: N0: 234 ,7 43, 652 ,37 8,4 23, 045,7 83, 479,556,7 93, 498,547, 534 ,684, ➥795,672 ,30 0,000,000,000,000 R: 234 7 436 5 237 84 230 457 834 795567 934 98547 534 68479567 230 948 235 987 439 0 From the Library of Skyla Walker 80 CHAPTER. .. Invariant 1 234 5.68 1 234 5.6789 F6 Integer, floating-point Invariant 1 234 5.678900 1 234 5.6789 e Integer, floating-point Invariant 1. 234 568e+004 1 234 5.6789 E Integer, floating-point Invariant 1. 234 568E+004 1 234 5.6789 E3 Integer, floating-point Invariant 1. 235 E+004 1 234 5.6789 N Integer, floating-point Invariant 12 ,34 5.68 1 234 5.6789 N0 Integer, floating-point Invariant 12 ,34 6 1 234 5.6789 N5 Integer, floating-point... Invariant 12 ,34 5.67890 1 234 5.6789 C Integer, floating-point en-US $12 ,34 5.68 continues From the Library of Skyla Walker 86 CHAPTER 5 Numbers TABLE 5.2 Number Format Strings (continued) Input Format String Types Allowed Culture Output 1 234 5.6789 C3 Integer, floating-point En-GB £12 ,34 5.679 0.1 234 5 P Integer, floating-point Invariant 12 .35 % 0.1 234 5 P1 Integer, floating-point Invariant 12 .3 % 1 234 5 D Integer... 12 .35 % 0.1 234 5 P1 Integer, floating-point Invariant 12 .3 % 1 234 5 D Integer Invariant 1 234 5 1 234 5 D8 Integer Invariant 0001 234 5 1 234 5 X Integer Invariant 30 39 1 234 5 X8 Integer Invariant 000 030 39 1 234 5.6789 000000.00 Integer, floating-point Invariant 01 234 5.68 1 234 5.6789 000,000.0 Integer, floating-point Invariant 012 ,34 5.7 Convert a String to a Number Scenario/Problem: You need to parse string input into... 0,00,12 ,34 5.68 (0001 234 5.679) nothing! Number Format Strings Summary Table 5.2 provides a summary of number format strings TABLE 5.2 Number Format Strings Input Format String Types Allowed Culture Output 1 234 5.6789 G Integer, floating-point Invariant 1 234 5.6789 1 234 5.6789 G4 Integer, floating-point Invariant 1. 235 E+04 1 234 5.6789 G5 Integer, floating-point Invariant 1 234 6 1 234 5.6789 F Integer, floating-point... you don’t lose data Given these questions, Table 5.1 demonstrates the differences TABLE 5.1 Floating-Point Types Precision (Digits) Type Range Float ±1.5×10–45 Double ±5.0×10 32 4 – ±1.7×1 030 8 Decimal ±1.0×10–28 – – 3. 4×1 038 ±7.9×1028 Largest Exact Integer Size 7 224 4 bytes 15–16 2 53 8 bytes 28–29 21 13 16 bytes Largest exact integer means the largest integer value that can be represented without loss... want shown (they will be zeropadded) Int32 number = 1 234 5; string hex = number.ToString(“X”, CultureInfo.InvariantCulture); //to get 0x before the number, do: string hexUsual = “0x” + number.Format(“X8”, CultureInfo.InvariantCulture); Console.WriteLine(hex); Console.WriteLine(hexBetter); The output is as follows: 30 39 0x000 030 39 From the Library of Skyla Walker 84 CHAPTER 5 Numbers Group Digits To group... Complex.Pow(a,2)); Console.WriteLine(“a / 0 = {0}”, a / Complex.Zero); //this will assign -1 to the real part, and 0 to the imaginary part Complex c = -1 ; Console.WriteLine(“c = {0}”, c); Console.WriteLine(“Sqrt(c) = {0}”, Complex.Sqrt(c)); This has the output a = (2, 1) b = (3, 2) a + b = (5, 3) pow(a,2) = (3, 4) a / 0 = (NaN, NaN) c = (-1 , 0) Sqrt(c) = (0, 1) Format a Complex Number While (a, b) is a valid format... another culture, do this: string frStr = -1 00 100 100,987”; double frVal = 0; bool success = double.TryParse(frStr, NumberStyles.Any, CultureInfo.CreateSpecificCulture(“fr-FR”), out frVal); Parse Hex Number To parse hexadecimal number strings, you must remove any “0x” that precedes the number before calling TryParse() string hexStr = “0x3 039 ”; Int32 hexVal = 0; if (Int32.TryParse(hexStr.Replace(“0x”,””),... every 3 digits Console.WriteLine(number.ToString(“00,000,000.00”, CultureInfo.CreateSpecificCulture(“hi-IN”))); //show different format for negative/zero numbers double neg = number * -1 ; Console.WriteLine(neg.ToString(“00,000,000.00;(00000000.000)”, ci)); double zero = 0.0; Console.WriteLine( ➥ zero.ToString(“00,000,000.00;(00000000.000);’nothing!’”, ci)); Here’s the output: 0001 234 5.68 00,012 ,34 5.68 . BetterAdd : IAdd { public UInt32 Add(UInt32 a, UInt32 b) { return a + b; } } void SomeFunc() { BetterAdd ba; //this will cause a contract exception ba.Add(UInt32.MaxValue, UInt32.MaxValue); } From the. a variable. Solution: The null-coalescing operator can simplify the syntax a bit. int? n = null; object obj = “Hello”; int x = 13; //short for if (n!=null) o = n; else o = -1 ; int? o = n ?? -1 ; object obj2. null //int y = x ?? -1 ; Console.WriteLine(“o = {0}”, o); Console.WriteLine(“obj2 = {0}”, obj2); The output is as follows: o = -1 obj2 = Hello From the Library of Skyla Walker ptg 54 CHAPTER 3 General Coding Add

Ngày đăng: 12/08/2014, 09:23

Mục lục

  • Part I: C# Fundamentals

    • 3 General Coding

      • Use the Conditional Operator (?:)

      • Use the Null-Coalescing Operator (??)

      • Add Methods to Existing Types with Extension Methods

      • Call Methods with Default Parameters

      • Call Methods with Named Parameters

      • Defer Evaluation of a Value Until Referenced

      • Enforce Code Contracts

      • 4 Exceptions

        • Throw an Exception

        • Catch an Exception

        • Catch Multiple Exceptions

        • Rethrow an Exception

        • (Almost) Guarantee Execution with finally

        • Get Useful Information from an Exception

        • Create Your Own Exception Class

        • Catch Unhandled Exceptions

        • Usage Guidelines

        • 5 Numbers

          • Decide Between Float, Double, and Decimal

          • Use Enormous Integers (BigInteger)

          • Use Complex Numbers

          • Format Numbers in a String

Tài liệu cùng người dùng

Tài liệu liên quan