Название | Professional C# 6 and .NET Core 1.0 |
---|---|
Автор произведения | Christian Nagel |
Жанр | Зарубежная образовательная литература |
Серия | |
Издательство | Зарубежная образовательная литература |
Год выпуска | 0 |
isbn | 9781119096634 |
As discussed earlier in this chapter, namespaces provide a way to organize related classes and other types. Unlike a file or a component, a namespace is a logical, rather than a physical, grouping. When you define a class in a C# file, you can include it within a namespace definition. Later, when you define another class that performs related work in another file, you can include it within the same namespace, creating a logical grouping that indicates to other developers using the classes how they are related and used:
Placing a type in a namespace effectively gives that type a long name, consisting of the type’s namespace as a series of names separated with periods (.), terminating with the name of the class. In the preceding example, the full name of the Subscriber struct is CustomerPhoneBookApp.Subscriber. This enables distinct classes with the same short name to be used within the same program without ambiguity. This full name is often called the fully qualified name.
You can also nest namespaces within other namespaces, creating a hierarchical structure for your types:
Each namespace name is composed of the names of the namespaces it resides within, separated with periods, starting with the outermost namespace and ending with its own short name. Therefore, the full name for the ProCSharp namespace is Wrox.ProCSharp, and the full name of the NamespaceExample class is Wrox.ProCSharp.Basics.NamespaceExample.
You can use this syntax to organize the namespaces in your namespace definitions too, so the previous code could also be written as follows:
Note that you are not permitted to declare a multipart namespace nested within another namespace.
Namespaces are not related to assemblies. It is perfectly acceptable to have different namespaces in the same assembly or to define types in the same namespace in different assemblies.
You should define the namespace hierarchy prior to starting a project. Generally the accepted format is CompanyName.ProjectName.SystemSection. In the previous example, Wrox is the company name, ProCSharp is the project, and in the case of this chapter, Basics is the section.
The using Directive
Obviously, namespaces can grow rather long and tiresome to type, and the capability to indicate a particular class with such specificity may not always be necessary. Fortunately, as noted earlier in this chapter, C# allows you to abbreviate a class’s full name. To do this, list the class’s namespace at the top of the file, prefixed with the using keyword. Throughout the rest of the file, you can refer to the types in the namespace simply by their type names:
As mentioned earlier, many C# files have the statement using System; simply because so many useful classes supplied by Microsoft are contained in the System namespace.
If two namespaces referenced by using statements contain a type of the same name, you need to use the full (or at least a longer) form of the name to ensure that the compiler knows which type to access. For example, suppose classes called NamespaceExample exist in both the Wrox.ProCSharp.Basics and Wrox.ProCSharp.OOP namespaces. If you then create a class called Test in the Wrox.ProCSharp namespace, and instantiate one of the NamespaceExample classes in this class, you need to specify which of these two classes you’re talking about:
Your organization will probably want to spend some time developing a namespace convention so that its developers can quickly locate functionality that they need and so that the names of the organization’s homegrown classes won’t conflict with those in off-the-shelf class libraries. Guidelines on establishing your own namespace convention, along with other naming recommendations, are discussed later in this chapter.
Namespace Aliases
Another use of the using keyword is to assign aliases to classes and namespaces. If you need to refer to a very long namespace name several times in your code but don’t want to include it in a simple using statement (for example, to avoid type name conflicts), you can assign an alias to the namespace. The syntax for this is as follows:
The following example (a modified version of the previous example) assigns the alias Introduction to the Wrox.ProCSharp.Basics namespace and uses this to instantiate a NamespaceExample object, which is defined in this namespace. Notice the use of the namespace alias qualifier (::). This forces the search to start with the Introduction namespace alias. If a class called Introduction had been introduced in the same scope, a conflict would occur. The :: operator enables the alias to be referenced even if the conflict exists. The NamespaceExample class has one method, GetNamespace, which uses the GetType method exposed by every class to access a Type object representing the class’s type. You use this object to return a name of the class’s namespace (code file NamespaceSample/Program.cs):
As described at the beginning of this chapter, C# programs start execution at a method named Main. Depending on the execution environment there are different requirements.
• Have a static modifier applied
• Be in a class with any name
• Return a type of int or void
Although it is common to specify the public modifier explicitly – because by definition the method must be called from outside the program – it doesn’t actually matter what accessibility level you assign to the entry-point method; it will run even if you mark the method as private.
The examples so far have shown only the Main method without any parameters. However, when the program is invoked, you can get the CLR to pass any command-line arguments to the program by including a parameter. This parameter is a string array, traditionally called args (although C# accepts any name). The program can use this array to access any options passed through the command line when the program is started.
The following example loops through the string array passed in to the Main method and writes the value of each option to the console window (code file ArgumentsSample/Program.cs):
For passing arguments to the program when running the application from Visual Studio 2015, you can define the arguments in the Debug section of the project properties as shown in Figure 2.9. Running the application reveals the result to show all argument values to the console.
The next topic – adding comments to your code – looks very simple on the surface, but it can be complex. Comments can be beneficial to other developers who may look at your code. Also, as you will see, you can use comments to generate documentation of your code for other developers to use.
Internal Comments Within the Source Files
As noted earlier in this chapter, C# uses the traditional C-type single-line (//..) and multiline (/* .. */) comments:
Everything in a single-line comment, from the // to the end of the line, is ignored by the compiler, and everything from an opening /* to the next */ in a multiline comment combination is ignored. Obviously, you can’t include the combination */ in any multiline comments, because this will be treated as the end of the comment.
It is possible