Temporarily Out of Stock Online
C# was designed from the ground up for development on Microsoft's .NET framework. As such, it's a high-performance language that's simple, safe, object-oriented, and Internet-centric. Programming C#, 2nd Edition teaches this new language in a way that experienced programmers will appreciateby grounding its applications firmly in the context of Microsoft's .NET platform and the development of desktop and Internet applications.The first part of this book introduces C# fundamentals, then goes on to explain:
- Classes and objects
- Inheritance and polymorphism
- Operator overloading
- Structs and interfaces
- Arrays, indexers, and collections
- String objects and regular expressions
- Exceptions and bug handling
- Delegates and events
|Publisher:||O'Reilly Media, Incorporated|
|Edition description:||Second Edition|
|Product dimensions:||7.04(w) x 9.21(h) x 1.15(d)|
About the Author
Jesse Liberty is the best selling author of Programming ASP.NET, Programming C#, and a dozen other books on web and object oriented programming. He is president of Liberty Associates, Inc., where he provides contract programming, consulting and on-site training in ASP.NET, C#, C++ and related topics. Jesse has been a Distinguished Software Engineer at AT&T and Vice President for technology development at CitiBank.
Read an Excerpt
Chapter 18: Attributes and Reflection
Throughout this book, I have emphasized that a .NET application contains code, data, and metadata. Metadata is information about the data--that is, information about the types, code, assembly, and so forth--that is stored along with your program. This chapter will explore how some of that metadata is created and used.
Attributes are a mechanism for adding metadata, such as compiler instructions and other data about your data, methods, and classes, to the program itself. Attributes are inserted into the metadata and are visible through ILDasm and other metadata-reading tools.
Reflection is the process by which a program can read its own metadata. A program is said to reflect on itself, extracting metadata from its assembly and using that metadata either to inform the user or to modify its own behavior.
An attribute is an object that represents data you want to associate with an element in your program. The element to which you attach an attribute is referred to as the target of that attribute. For example, the attribute:
is associated with a class or an interface to indicate that the target class should derive from
IUnknown rather than
IDispatch, when exporting to COM. COM interface programming is discussed in detail in Chapter 22.
In Chapter 17, you saw this attribute:
This inserts metadata into the assembly to designate the program's
Attributes come in two flavors: intrinsic and custom. Intrinsic attributes are supplied as part of the Common Language Runtime (CLR), and they are integrated into .NET. Custom attributes are attributes you create for your own purposes.
Most programmers will use only intrinsic attributes, though custom attributes can be a powerful tool when combined with reflection, described later in this chapter.
If you search through the CLR, you'll find a great many attributes. Some attributes are applied to an assembly, others to a class or interface, and some, such as
[WebMethod], to class members. These are called the attribute targets. Possible attribute targets are detailed in Table 18-1.
Applied to any of the following elements: assembly, class, class member, delegate, enum, event, field, interface, method, module, parameter, property, return value, or struct
Applied to the assembly itself
Applied to instances of the class
Applied to classes, structs, enums, constructors, methods, properties, fields, events, delegates, and interfaces
Applied to a given constructor
Applied to the delegated method
Applied to an enumeration
Applied to an event
Applied to a field
Applied to an interface
Applied to a method
Applied to a single module
Applied to a parameter of a method
Applied to a property (both
Applied to a return value
Applied to a struct
You apply attributes to their targets by placing them in square brackets immediately before the target item. You can combine attributes, either by stacking one on top of another:
or by separating the attributes with commas:
TIP: You must place assembly attributes after all
usingstatements and before any code.
Many intrinsic attributes are used for interoperating with COM, as discussed in detail in Chapter 22. You've already seen use of one attribute (
[WebMethod]) in Chapter 16. You'll see other attributes, such as the
[Serializable] attribute, used in the discussion of serialization in Chapter 19.
System.Runtime namespace offers a number of intrinsic attributes, including attributes for assemblies (such as the
keyname attribute), for configuration (such as
debug to indicate the debug build), and for version attributes.
You can organize the intrinsic attributes by how they are used. The principal intrinsic attributes are those used for COM, those used to modify the Interface Definition Language (IDL) file from within a source-code file, attributes used by the ATL Server classes, and attributes used by the Visual C++ compiler.
Perhaps the attribute you are most likely to use in your everyday C# programming (if you are not interacting with COM) is
[Serializable]. As you'll see in Chapter 19, all you need to do to ensure that your class can be serialized to disk or to the Internet is add the
[Serializable] attribute to the class:
The attribute tag is put in square brackets immediately before its target--in this case, the class declaration.
The key fact about intrinsic attributes is that you know when you need them; the task will dictate their use.
You are free to create your own custom attributes and use them at runtime as you see fit. Suppose, for example, that your development organization wants to keep track of bug fixes. You already keep a database of all your bugs, but you'd like to tie your bug reports to specific fixes in the code.
You might add comments to your code along the lines of:
// Bug 323 fixed by Jesse Liberty 1/1/2005.
This would make it easy to see in your source code, but there is no enforced connection to Bug 323 in the database. A custom attribute might be just what you need. You would replace your comment with something like this:
Comment="Off by one error"]
You could then write a program to read through the metadata to find these bug-fix notations and update the database. The attribute would serve the purposes of a comment, but would also allow you to retrieve the information programmatically through tools you'd create.
Declaring an Attribute
Attributes, like most things in C#, are embodied in classes. To create a custom attribute, you derive your new custom attribute class from
public class BugFixAttribute : System.Attribute
You need to tell the compiler with which kinds of elements this attribute can be used (the attribute target). You specify this with (what else?) an attribute:
AllowMultiple = true)]
AttributeUsage is an attribute applied to attributes: a meta-attribute. It provides, if you will, meta-metadata--that is, data about the metadata. For the
AttributeUsage attribute constructor, you pass two arguments. The first argument is a set of flags that indicate the target--in this case, the class and its constructor, fields, methods, and properties. The second argument is a flag that indicates whether a given element might receive more than one such attribute. In this example,
AllowMultiple is set to
true, indicating that class members can have more than one
Naming an Attribute
The new custom attribute in this example is named
BugFixAttribute. The convention is to append the word
Attribute to your attribute name. The compiler supports this by allowing you to call the attribute with the shorter version of the name. Thus, you can write:
[BugFix(123, "Jesse Liberty", "01/01/05", Comment="Off by one")]
The compiler will first look for an attribute named
BugFix and, if it does not find that, will then look for
Constructing an Attribute
Every attribute must have at least one constructor. Attributes take two types of parameters, positional and named. In the
BugFix example, the programmer's name and the date are positional parameters, and
comment is a named parameter. Positional parameters are passed in through the constructor and must be passed in the order declared in the constructor:
public BugFixAttribute(int bugID, string programmer,
this.bugID = bugID;
this.programmer = programmer;
this.date = date;
Named parameters are implemented as properties:
public string Comment
comment = value;
It is common to create read-only properties for the positional parameters:
public int BugID
Using an Attribute
Once you have defined an attribute, you can put it to work by placing it immediately before its target. To test the
BugFixAttribute of the preceding example, the following program creates a simple class named
MyMath and gives it two functions. You'll assign
BugFixAttributes to the class to record its code-maintenance history...
Table of Contents
The C# Language
Chapter 1: C# and the .NET Framework
Chapter 2: Getting Started: “Hello World”
Chapter 3: C# Language Fundamentals
Chapter 4: Classes and Objects
Chapter 5: Inheritance and Polymorphism
Chapter 6: Operator Overloading
Chapter 7: Structs
Chapter 8: Interfaces
Chapter 9: Arrays, Indexers, and Collections
Chapter 10: Strings and Regular Expressions
Chapter 11: Handling Exceptions
Chapter 12: Delegates and Events
Programming with C#
Chapter 13: Building Windows Applications
Chapter 14: Accessing Data with ADO.NET
Chapter 15: Programming Web Applicationswith Web Forms
Chapter 16: Programming Web Services
The CLR and the .NET Framework
Chapter 17: Assemblies and Versioning
Chapter 18: Attributes and Reflection
Chapter 19: Marshaling and Remoting
Chapter 20: Threads and Synchronization
Chapter 21: Streams
Chapter 22: Programming .NET and COM
Most Helpful Customer Reviews
This is a great book for learning C#. The first part is an excellent tutorial in the language, just right for experienced C, C++ and Java programmers and for advanced VB6 programmers. Jesse Liberty is a computer consultant, trainer, and author. He specialized in object-oriented analysis and design, C++, VB, ASP, and web programming. The second part introduces how to use the language to create .net programs. This is a bit superficial, but his goal was only to provide an introduction, and it is a very good introduction. For more detail on really building advanced applications you will need an additional book (like his book on ASP.NET). The third part of Programming C# goes into advanced topics you won't easily find elsewhere, with excellent coverage of (for example) threading, remoting, reflection, streams and so forth. Liberty writes well, his examples are terrific, and he makes complex material easily understandable. Further, he supports his book on his web site where he provides not only source code but a discussion center where you can ask questions. I highly recommend this excellent tutorial.