Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 135 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
135
Dung lượng
1,96 MB
Nội dung
Part V: Additional Techniques 1044 A similar method is used to set the Inherited property. If a custom attribute has properties, then you can set these in the same manner. One example might be to add the name of the person who fixed the bug: public readonly string BugNumber; public readonly string Comments; public readonly string Author; public override string ToString () { if (string.IsNullOrEmpty(Author)) return string.Format (“BugFix {0} : {1}” , BugNumber , Comments); else return string.Format (“BugFix {0} by {1} : {2}” , BugNumber , Author , Comments); } This adds the Author field and an overridden ToString() implementation that displays the full details if the Author field is set. If the Author property is not defined when you attribute your code, then the output from the BugFix attribute just shows the bug number and comments. The ToString() method would be used to display a list of bug fixes for a given section of code — perhaps to print and file away somewhere. Once you have written the BugFix attribute, you need some way to report the fixes made on a class and the members of that class. The way to report bug fixes for a class is to pass the class type (again a System.Type ) to the following DisplayFixes function. This also uses reflection to find any bug fixes applied to the class, and then iterates through all methods of that class looking for BugFix attributes: public static void DisplayFixes (System.Type t) { // Get all bug fixes for the given type, // which is assumed to be a class. object[] fixes = t.GetCustomAttributes (typeof (BugFixAttribute) , false); Console.WriteLine (“Displaying fixes for {0}” , t); // Display the big fix information. foreach (BugFixAttribute bugFix in fixes) Console.WriteLine (“ {0}” , bugFix); // Now get all members (i.e., functions) of the class. foreach (MemberInfo member in t.GetMembers (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) { // And find any big fixes applied to these too. object[] memberFixes = member.GetCustomAttributes(typeof(BugFixAttribute) , false); if (memberFixes.Length > 0) { c30.indd 1044c30.indd 1044 3/25/08 12:33:17 PM3/25/08 12:33:17 PM Chapter 30: Attributes 1045 Console.WriteLine (“ {0}” , member.Name); // Loop through and display these. foreach (BugFixAttribute memberFix in memberFixes) Console.WriteLine (“ {0}” , memberFix); } } } The code first retrieves all BugFix attributes from the type itself: object[] fixes = t.GetCustomAttributes (typeof (BugFixAttribute), false); These are enumerated and displayed. The code then loops through all members defined on the class, by using the GetMembers() method: foreach (MemberInfo member in t.GetMembers ( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) GetMembers retrieves properties, methods, and fields from a given type. To limit the list of members that are returned, the BindingFlags enum is used (which is defined within System.Reflection ). The binding flags passed to this method indicate which members you are interested in — in this case, you ’ d like all instance and static members, regardless of visibility, so you specify Instance and Static , together with Public and NonPublic members. After getting all members, you loop through these, finding any BugFix attributes associated with the particular member, and output these to the console. To output a list of bug fixes for a given class, you just call the static DisplayFixes() method, passing in the class type: BugFixAttribute.DisplayFixes (typeof (MyBuggyCode)); For the MyBuggyCode class presented earlier, this results in the following output: Displaying fixes for MyBuggyCode BugFix 101 : Created some methods DoSomething BugFix 2112 : Returned a non-null string BugFix 38382 : Returned OK .ctor BugFix 90125 : Removed call to base() If you wanted to display fixes for all classes in a given assembly, you could use reflection to get all the types from the assembly, and pass each one to the static BugFixAttribute.DisplayFixes method. c30.indd 1045c30.indd 1045 3/25/08 12:33:17 PM3/25/08 12:33:17 PM Part V: Additional Techniques 1046 AttributeUsage.Inherited An attribute may be defined as inheritable by setting this flag when defining the custom attribute: [AttributeUsage (AttributeTargets.Class, Inherited = true)] public class BugFixAttribute { } This indicates that the BugFix attribute will be inherited by any subclasses of the class using the attribute, which may or may not be desirable. In the case of the BugFix attribute, this behavior would probably not be desirable, because a bug fix normally applies to a single class and not the derived classes. Suppose you have the following abstract class with a bug fix applied: [BugFix(“38383”,”Fixed that abstract bug”)] public abstract class GenericRow : DataRow { public GenericRow (System.Data.DataRowBuilder builder) : base (builder) { } } If you created a subclass from this class, you wouldn ’ t want the same BugFix attribute to be reflected in the subclass — the subclass has not had that fix done on it. However, if you were defining a set of attributes that linked members of a class to fields in a database table, then you probably would want to inherit these attributes. Armed with the knowledge you now have about custom attributes, you can probably think of several places where adding extra information to assemblies is useful. You could take the BugFix attribute defined here and extend it too — one example would be to define the version number of the software that the bug was fixed in. That would enable you to display to end users all bugs fixed for a given version of your application simply by using reflection to find the BugFix attributes and then checking the version number of that fix against the versions that the end user has asked to see. This would also be great for producing documentation at the end of a product cycle to list all fixes made in the latest version. Obviously, you have to rely on the developers to add in these attributes, but it could be made part of the code review cycle to ensure that all fixes were documented within the code. Summary This chapter described what attributes are and discussed some of the attributes defined within the .NET Framework. There are many more attribute classes within the framework, and the best way to find out what they are used for is to look through the .NET Framework SDK documentation. To find all attributes in an assembly, just load it into Reflector, browse for the System.Attribute class, and then display the derived types. You may be surprised at just how many attributes are defined within .NET. c30.indd 1046c30.indd 1046 3/25/08 12:33:18 PM3/25/08 12:33:18 PM Chapter 30: Attributes 1047 In this chapter, you learned about the following attribute - related topics: Using the Conditional attribute to exclude debugging code from release mode binaries . Using the Obsolete attribute to revise libraries over time . How serialization uses attributes to specify what should and what should not be serialized . How to delay - sign an assembly . How to create custom attributes. Attributes are a powerful way to add extra, out - of - band information to your assemblies. You can create your own attributes to add extra information to your classes as appropriate. This chapter described how to create a BugFix attribute, which could be used to provide a link between the source code that was fixed and the bug originally raised by an end user. There are many other uses of attributes — and you are encouraged to look into the .NET Framework for other attribute classes. ❑ ❑ ❑ ❑ ❑ c30.indd 1047c30.indd 1047 3/25/08 12:33:18 PM3/25/08 12:33:18 PM c30.indd 1048c30.indd 1048 3/25/08 12:33:18 PM3/25/08 12:33:18 PM 31 XML Documentation Up to this point in this book, you ’ ve seen the entire C# language and a great many things you can do with it, including both Web and Windows programming. Along the way, you ’ ve seen and made extensive use of the IntelliSense feature in Visual Studio. This helpful tool dramatically reduces the amount of typing you have to do, because it suggests keywords, type names, variable names, and parameters as you type. It also makes it easier to remember what methods and properties you have at your disposal and often tells you exactly how to use them. However, the classes you have made have suffered slightly here. While the classes and member names are suggested for you, no handy hints pop up telling you how to do things. To achieve the kind of behavior that you see with the .NET Framework types, you need to use XML documentation . XML documentation enables you to include syntax, help, and examples for the classes you create at the source - code level. This information may then be used to provide IntelliSense information for Visual Studio as discussed previously, but there are other possibilities. You can use XML documentation as a starting point for full, MSDN - link documentation of your projects. You can also style the XML documentation using XSLT to obtain instant HTML documentation with very little effort. You have seen in earlier chapters just how versatile XML is, and you can use all of its power in the development and production life cycle of your applications. Documentation is particularly important when you are working as part of a team, as it enables you to show exactly how your types work. It can also be very useful to end users if you are creating an SDK or similar product where you expect people to use your classes from their code. Having the facility to create this documentation built into the tool you use to develop code is a very powerful feature. Although adding XML documentation to your code can be a time - consuming process, the result is well worth it. Dropping text in as you develop can make things easier in the long run and provide you with a handy quick reference that will help to avoid confusion when the amount of classes in your project starts getting out of hand. In this chapter, you will learn two main things: How to add and view basic XML documentation How to use XML documentation ❑ ❑ c31.indd 1049c31.indd 1049 3/25/08 12:36:32 PM3/25/08 12:36:32 PM Part V: Additional Techniques 1050 Adding XML Documentation Adding XML documentation to your code is a remarkably simple thing to do. As with attributes, which you examined in the previous chapter, you can apply XML documentation to any type or member by placing it on lines just before the member. XML documentation is added by using an extended version of C# comment syntax, with three front slashes instead of two. For example, the following code shows how to place XML documentation in a source code file for a class called MyClass , and a method of that class, MyMethod() : /// (XML Documentation goes here.) class MyClass { /// (And here.) public void MyMethod() { } } XML documentation cannot be applied to namespace declarations. Typically, XML documentation will span multiple lines and be marked up by using the XML documentation vocabulary: /// < XMLDocElement > /// Content. /// More content. /// < / XMLDocElement > class MyClass { Here, < XMLDocElement > is one of several available elements, and may contain nested elements, some of which use attributes to further specify functionality. Note that the /// parts of the lines of code containing XML documentation are completely ignored and treated as whitespace. They are necessary to prevent the compiler from thinking that the lines of documentation can be interpreted as code, which would lead to compiler errors. The most basic element for XML documentation is < summary > , and it provides a short description of a type or member. Before moving on to anything more complicated, you should take a look at the following example, which illustrates this element and how the results become visible. Try It Out Adding and Viewing Basic XML Documentation 1. Create a new console application called FirstXMLDocumentation and save it in the directory C:\BegVCSharp\Chapter31. 2. Add a class called DocumentedClass . c31.indd 1050c31.indd 1050 3/25/08 12:36:33 PM3/25/08 12:36:33 PM Chapter 31: XML Documentation 1051 3. Open the code for DocumentedClass , make the class definition public, add a new line before the class declaration, and type /// (three forward slashes). 4. Note that the IDE auto - completion adds the following code, placing the cursor inside the < summary > element: namespace FirstXMLDocumentation { /// < summary > /// /// < /summary > public class DocumentedClass { 5. Add the following text to the < summary > element: namespace FirstXMLDocumentation { /// < summary > /// This is a summary description for the DocumentedClass class. /// < /summary > public class DocumentedClass { 6. In Program.cs , type doc in the Main() method and note the IntelliSense information that pops up, shown in Figure 31 - 1 . Figure 31-1 c31.indd 1051c31.indd 1051 3/25/08 12:36:33 PM3/25/08 12:36:33 PM Part V: Additional Techniques 1052 7. Open the Object Browser widow and expand the entry for the FirstXMLDocumentation project until you can click DocumentedClass . Note the summary information displayed in the bottom - right pane, as shown in Figure 31 - 2 . Figure 31-2 How It Works This example demonstrates the basic technique for adding XML documentation and how this documentation is used in the IDE. When adding the basic summary information for your DocumentedClass class, you saw how the IDE dynamically detects what you have in mind and fills out the basic code for you. IntelliSense and the Object Browser detect the documentation you added without even having to compile the project. These basic techniques apply to all aspects of XML documentation and make it easy to add and consume this information. XML Documentation Comments You can in fact add any XML you like to the XML documentation of a target (by target we mean type or member ). However, some recommended elements and attributes will help your documentation to meet standard guidelines. The recommended XML is enough for most situations, and following this standard means that tools that consume XML documentation (including IntelliSense and the Object Browser) can interpret your documentation effectively. Brief descriptions of the basic elements for XML documentation are shown in the following table. You ’ ll look at each of these in more depth in subsequent sections. c31.indd 1052c31.indd 1052 3/25/08 12:36:33 PM3/25/08 12:36:33 PM Chapter 31: XML Documentation 1053 Element Description < c > Formats text in code font. Use this for individual code words embedded in other text. < code > Formats text in code font. Use this for multiple lines of code, not embedded in other text. < description > Marks text as being an item description. Used as a child element of < item > or < listheader > in lists. < example > Marks text as an example usage of the target . < exception > Specifies an exception that may be thrown by the target . < include > Gets XML documentation from an external file . < item > Represents an item in a list. Used as a child of < list > , and can have < description > and < term > children. < list > Defines a list. Can have < listheader > and < item > children. < listheader > Represents the header row of a tabular list. Used as a child of < list > , and can have < description > and < term > children. < para > Used to break text into separate paragraphs . < param > Describes a parameter of the target . < paramref > References a method parameter . < permission > Specifies the permissions required for the target . < remarks > Includes additional information concerning the target . < returns > Describes the return value of the target; used with methods . < see > References another target used in the body of an element such as < summary > . < seealso > References another target, usually used outside of other elements, or at the end of, for example, < summary > . < summary > Holds summary information concerning the target . < term > Marks text as being an item definition. Used as a child element of < item > or < listheader > in lists. < typeparam > Describes a type parameter for a generic target . < typeparamref > References a type parameter . < value > Describes the return value of the target; used with properties . c31.indd 1053c31.indd 1053 3/25/08 12:36:34 PM3/25/08 12:36:34 PM [...]... www .microsoft. com You should get output that looks similar to the following: Host: lb1.www.ms.akadns.net Address(es): Address: 207.46. 193 .254 Address: 207.46. 19. 190 Address: 207.46. 19. 254 Address: 207.46. 192 .254 10 79 c32.indd 10 79 3/24/08 5:31: 29 PM ... : Intel(R) PRO/Wireless 394 5ABG Network Connection Physical address : 00-13-02-38-0D-5C DHCP Enabled : Yes Autoconfiguration Enabled : Yes Link-local IPv6 Address : fe80:bd:3d27:4106:9f4c%10(Preferred) IPv4 Address : 192 .168.0.31(Preferred) Subnet Mask : 255.255.255.0 Lease Obtained : Sunday, July 29, 2007, 3:10:08 PM Lease Expires ... Obtained : Sunday, July 29, 2007, 3:10:08 PM Lease Expires : Wednesday, August 01, 2007, 3:10:08 PM Default Gateway : 192 .168.0.6 DHCP Server : 192 .168.0.6 DHCPv6 IAID : 167777026 DNS Servers : 192 .168.0.10 195 .202.128.2 NetBIOS over Tcpip : Enabled 1077 c32.indd 1077 3/24/08 5:31:28 PM Part V: Additional Techniques The network layer uses... www .microsoft. com To start it from Visual Studio, you can set the command-line arguments with the Debug configuration, as shown in Figure 32-4 You can also start a command prompt, change to the directory of the executable, and start the application with dnslookup www .microsoft. com You should get output that looks similar to the following: Host: lb1.www.ms.akadns.net Address(es): Address: 207.46. 193 .254... particularly useful to refer to C# keywords using an alternative attribute, langword: /// /// For more information, see /// The benefit here is that because you have specified a language-specific keyword, it is possible to refactor the documentation for other languages, such as Visual Basic The null keyword in C# is equivalent to Nothing in Visual Basic, so it would... Console.WriteLine(“- {0}”, node.Attributes[“name”].Value.Substring(2)); } Console.ReadKey(); } 4 Execute the application The result is shown in Figure 31 -9 Figure 31 -9 How It Works This example demonstrates the basics of loading and processing an XML documentation file in C# code You start by loading in a documentation file, which in this case is the one generated by the DocumentedClasses type library: XmlDocument... read on a narrow page Next, you get a list of all the elements by using the simple XPath expression //member: XmlNodeList memberNodes = documentation.SelectNodes(“//member”); 10 69 c31.indd 10 69 3/25/08 12:36: 39 PM Part V: Additional Techniques When you have a list of elements, you can search through them, looking for those that start with a T to get the elements that refer to types,... myGarden.Add(new Bench(4, 2)); Bench(10, 2)); Sprinkler(20, 10)); Tree(3, 13)); Tree(25, 7)); Tree(35, 15)); Flower(36, 0)); Flower(37, 0)); Flower(38, 0)); Flower( 39, 0)); Flower(37, 1)); Flower(38, 1)); Flower( 39, 1)); Flower(37, 2)); Flower(38, 2)); Flower( 39, 2)); Statue(16, 3)); Bush(20, 17)); char[,] plan = myGarden.GetPlan(); for (int y = 0; y < gardenDepth; y++) { for (int x = 0; x < gardenWidth; x++) {... or an IP address can be resolved to its hostname Let’s try it out with a simple project Try It Out Using DNS 1 Create a new C# console application project named DnsLookup in the directory C:\BegVCSharp\Chapter32 2 Import the namespace System.Net 1078 c32.indd 1078 3/24/08 5:31: 29 PM Chapter 32: Networking 3 Invoke the GetHostEntry()method of the Dns class, as shown here, after checking the arguments... as adding it manually, but you do get the advantage of being able to do things very quickly, without having to remember any XML syntax You’ll see the capabilities in the following Try It Out 10 59 c31.indd 10 59 3/25/08 12:36:36 PM Part V: Additional Techniques Try It Out Adding XML Documentation in a Class Diagram 1 Create a new class library application called DiagrammaticDocumentation and save it in . possible to refactor the documentation for other languages, such as Visual Basic. The null keyword in C# is equivalent to Nothing in Visual Basic, so it would be possible to cater to both languages. How to add and view basic XML documentation How to use XML documentation ❑ ❑ c31.indd 1049c31.indd 10 49 3/25/08 12:36:32 PM3/25/08 12:36:32 PM Part V: Additional Techniques 1050 Adding XML Documentation. entire C# language and a great many things you can do with it, including both Web and Windows programming. Along the way, you ’ ve seen and made extensive use of the IntelliSense feature in Visual