当前位置:网站首页>. Net C Foundation (6): namespace - scope with name
. Net C Foundation (6): namespace - scope with name
2022-06-11 14:05:00 【qq_ forty-three million four hundred and seventy-nine thousand 】
High quality resource sharing
| Learning route guidance ( Click unlock ) | Knowledge orientation | Crowd positioning |
|---|---|---|
| 🧡 Python Actual wechat ordering applet 🧡 | Progressive class | This course is python flask+ Perfect combination of wechat applet , From the deployment of Tencent to the launch of the project , Create a full stack ordering system . |
| Python Quantitative trading practice | beginner | Take you hand in hand to create an easy to expand 、 More secure 、 More efficient quantitative trading system |
0. The purpose of the article
oriented C# New scholar , Introduce namespaces (namespace) And C# Namespace in .
1. Fundamentals of reading
understand C And C# The basic grammar of language .
Understanding scope concepts .
2. Name conflicts with namespace
2.1 An example of life
Suppose cat head has a name in Beijing AAA Friend, , There are two in Shanghai called AAA Friend, , Two in Shanghai AAA One likes salty rice dumplings , One likes sweet dumplings . One day, cat cat played with her friends , Asked the friend :
“AAA How is everything going recently? ”,
However, the cat has three names AAA Friend, , So cat cat is not sure what his friend is asking AAA, So the friend asked :
“ The one in Shanghai AAA How is everything going recently? ”
A little more precise , But that's not enough , Because cat and cat head met two people in Shanghai AAA Friend, , So the friend asked again :
“ The one in Shanghai likes salty zongzi AAA How is everything going recently? .
Come here , Maomaotou decides which Xiao Ming his friend asked . in other words , By Region + like + full name , A cat's head can determine who a friend refers to .
In this case , Decorate by layer by layer , We have gradually moved from precise positioning to specified AAA. In reality , Modify by various restrictions , We can distinguish people or things with similar names , The same is true for programs .
2.2 from C Language defects to namespaces
(1) Function naming conflict
Before we talk about namespaces , Let's take a look first C Some problems in language . Suppose you and your partner develop a C Program , And you happen to define two functions with the same function name :
void Init() { } // Initialize console
void Init() { } // Initialize printer
Suppose the two functions do completely different things ( One to initialize the console (Console), One to initialize the printer (Printer)) And cannot merge , So it is obvious that there is a way to distinguish the two functions . After a brief discussion , You and your friends decide to add the function object name before each function name to distinguish , So you changed the function name to the following :
void ConsoleInit() { } // For initializing the console Init
void PrinterInit() { } // Used to initialize the printer Init
With the development progress , You may create more and more functions with the same name , Finally, the function name will likely look like the following :
void ConsoleInit() { }
void ConsoleFoo() { }
void ConsoleWhatever() { }
void ConsolePrint(const char* s) { }
...
void PrinterInit() { }
void PrinterFoo() { }
void PrinterWhatever() { }
void PrinterPrint(const char* s) { }
...
Of course, such function names are not bad , But the function name contains unnecessary redundant information , Using this function name makes the code less readable , what's more , This will also greatly increase the number of characters that need to be entered when writing code :
ConsoleInit();
ConsoleFoo();
ConsoleWhatever();
ConsolePrint("...");
In the above code , The functions you use have been added before Console Prefix , Even then, you can know that you are operating the console most of the time , here , Whether using or reading , These prefixes are just superfluous for you . On the other hand , Suppose there is a way for the compiler to automatically add the names of all functions used in a certain range ‘Console’ Prefix , For example, like this :
// Tell the compiler to add... To all function names in the following code block Console Prefix
{
Init(); // From the compiler's point of view ConsoleInit
Foo(); // From the compiler's point of view ConsoleFoo
Whatever(); // From the compiler's point of view ConsoleWhatever
Print("..."); // From the compiler's point of view ConsolePrint
}
At this point, you don't have to input many unnecessary Console Prefix , It is much easier to use functions .
(2) Let the compiler do it for you
For the above reasons , You can define a syntax that tells the compiler to add the specified prefix to the function names used next , for example :
// Use namespace Keyword tells the compiler to add... To all function names in subsequent code blocks Console Prefix
namespace Console
{
Init();
Foo();
Whatever();
Print("...");
}
ad locum , We set to use namespace Keyword to tell the compiler to add the following specified for all functions in the following code block Console Prefix , So in the compiler's view , The actual code above is as follows :
ConsoleInit();
ConsoleFoo();
ConsoleWhatever();
ConsolePrint("...");
Obviously, at this time, the program can still accurately call the appropriate function . Again , Since you can let the compiler automatically prefix a function when it is called , Naturally, you can also make it automatically prefix function names when defining functions :
namespace Console // Automatically add... For members in subsequent code blocks Console Prefix
{
void Init() { ... }
void Foo() { ... }
void Whatever() { ... }
void Print(const char* s) { ... }
}
such , After the compiler performs automatic conversion , The above code will look like the following :
void ConsoleInit() { }
void ConsoleFoo() { }
void ConsoleWhatever() { }
void ConsolePrint(const char* s) { }
With this automatic prefix Syntax , When performing relevant operations on the console , You can operate as follows :
// Use namespace Keyword tells the compiler to add... To all function names in subsequent code blocks Console Prefix
namespace Console
{
void Init() // Definition init function ( The full name of the function is ConsoleInit)
{
...
}
void Launch() // Definition Launch function ( The full name of the function is ConsoleLaunch), And call the previously defined... In the function Init Method
{
Init(); // The Init namely ConsoleInit
...
}
}
When the printer is operated , It just needs :
// Use namespace Keyword tells the compiler to add... To all function names in subsequent code blocks Printer Prefix
namespace Printer
{
void Init() // Definition init function ( The full name of the function is PrinterInit)
{
...
}
void Launch() // Definition Launch function ( The full name of the function is PrinterLaunch), And call the previously defined... In the function Init Method
{
Init(); // The Init namely PrinterInit
...
}
}
obviously , With the syntax of adding prefixes automatically , It is convenient to define and use functions .
A step closer , You can also add prefixes using nested syntax :
namespace MeAndFriend // Automatically add... For members in subsequent code blocks MeAndFriend Prefix
{
namespace Console // Automatically add... For members in subsequent code blocks Console Prefix
{
void Init() { } // here Init Actually it should be called MeAndFriendConsoleInit
// ...
}
namespace Printer // Automatically add... For members in subsequent code blocks Printer Prefix
{
void Init() { } // here Init Actually it should be called MeAndFriendPrinterInit
// ...
}
}
such , For example, the above code will be generated by the compiler ‘MeAndFriendConsoleInit’ And ‘MeAndFriendPrinterInit’ This would have been a very long function name .
2.3 Scope and namespace
In the above code , We define a syntax to denote a prefix for a member in a code block :
// Tell the compiler that all members in the code block have... By default Console Prefix
namespace Console
{
...
}
At this point in the compiler's view , All in namespace Console The members in the scope of the following code block have their own Console Prefix . For the scope , adopt namespace keyword , We gave it a name Console, in other words , This is a scope with a name , And this named scope , Is the so-called namespace ( Or you can call it a namespace / Namespace ). Namespace (namespace) Medium “ name (name)” Part is a qualifying modifier , And its “ Space (space)” This is the scope of the qualifying modifier .
It seems that namespaces are not necessary , For example, if it is to avoid function name conflicts , Then you can manually add various qualifiers to function names to avoid conflicts , However, as we have seen before , If every function needs to input so much additional information unrelated to what the function does when it is defined and called , So this is an extra burden to input and read the code , And it may bring a lot of inconvenience to possible code modification in the future , The concept of namespace has alleviated this problem to a great extent .
3. C# The namespace in
Namespaces are such useful things , As a result, many modern programming languages have designs similar to namespaces .C# Naturally, it has its own namespace system ,MSDN The namespace is defined on ‘ A scope that contains a set of related objects ’, This concept is a bit abstract , Next, we will understand from the specific use .
3.1 Basic use
3.1.1 namespace keyword
(1) Global namespace
By default , There is a root space called the global namespace , This space is anonymous and implicit , Have global scope . So if a type is not defined under any declared namespace , It is directly located in the global namespace by default .
(2) Declare a namespace
Obviously, if you only have a global namespace, it doesn't make much sense , You should also be able to declare specific namespaces , To be in C# Declare a namespace in , Just use namespace Keyword plus a space name and a pair of curly braces ( That is, define code blocks ) that will do , The following code declares a namespace Alpha:
namespace Alpha
{
}
Again , Namespaces can also be nested with declarations :
namespace Alpha
{
namespace Beta
{
}
}
(Beta Is nested in Alpha A subspace in , and Alpha It is Beta The parent space of )
But according to the format specification , If you nest namespaces like above , A lot of column indentation is wasted when formatting code styles ( The code in each level of code block needs to be indented 4 A space , So every extra layer of namespaces causes all code to be indented more 4 A space ). So you can also use a period . To connect namespaces to represent nested relationships of namespaces , The above nested namespaces can also be declared as follows :
namespace Alpha.Beta
{
}
It should be noted that , All namespaces can be considered as subspaces of the global namespace , And if we write a namespace from the global namespace , Name this namespace as “ Fully qualified namespace ”. As defined in the above namespace , When expressed Beta Namespace ,Alpha.Beta Is a fully qualified namespace , and Beta Is not a fully qualified namespace . in addition , Although the global namespace is anonymous , But you can use global Keyword to refer to , And then use ::( instead of .) Join subspaces , therefore , Fully qualified namespace Alpha.Beta It can also be expressed as :
global::Alpha.Beta
( Yes C++ My friend should have a kind of ** Familiarity )
(2) Define types in namespaces
All types defined within the scope of a code block in a namespace belong to that namespace , For example, in the following code ,Foo Belong to Alpha Namespace :
namespace Alpha
{
class Foo
{
}
}
The above code is in namespace Alpha Define a Foo object , At this point, according to our previous explanation of the actual role of namespaces , Use a period . To connect namespace and type name , that Foo The full name of the type should be Alpha.Foo, in other words , The name of the namespace and the type name under the namespace can form a more explicit type name , therefore , Definitions like this do not conflict :
namespace Alpha
{
class Foo
{
}
}
namespace Beta
{
class Foo
{
}
}
Although there are two names in the above code Foo Class , But the two one. Foo The full names of are Alpha.Foo And Beta.Foo, From the compiler's point of view, these can be two completely different types . The full name of a type is the fully qualified namespace to which it belongs plus the type name , For example, for the following nested namespaces Alpha.Beta Of Foo class :
// Or simplified nested writing
// namespace Alpha.Beta
namespace Alpha
{
namespace Beta
{
class Foo // Alpha.Beta.Foo
{
}
}
}
Foo The full name of the type should be Alpha.Beta.Foo instead of Beta.Foo, For the convenience of the following description , We will ‘ With Fully qualified namespace . Type name Type name of format expression ’ be called ‘ Full type name ’.
3.1.2 using keyword
(1) Cross namespace access
Between types in the same namespace scope, you can directly use the type name to access , for example :
namespace Alpha
{
class Foo { }
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo(); // Use it directly Foo Express Alpha.Foo
}
}
}
type Foo The full type name of is Alpha.Foo, But because of Program Class is also in Alpha Namespace scope , So you can use Foo To express Alpha.Foo, This rule also applies to its nested space :
namespace Alpha
{
class Foo { } // Defined as Alpha Under space Foo type
namespace Beta // Beta yes Alpha The subspace of
{
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo(); // You can also directly use the class name to indicate the type
}
}
}
}
( For example, it can be considered that when types of the same namespace access each other, they default to each other's own space name prefix )
On the other hand , If you want to use a type defined in a subspace , You can use the Subspace name . Type name visit :
namespace Alpha
{
namespace Beta // Beta yes Alpha Nested namespace of
{
class Cat { } // It's defined in Alpha.Beta Under the Cat class
}
class Program
{
static void Main(string[] args)
{
Beta.Cat cat = new Beta.Cat(); // Use the subspace name + Type name specifies the type
}
}
}
However , If you want to use in other namespaces Alpha Under the namespace Foo, You need to use its full type name Alpha.Foo, For example, in Test Namespace Alpha.Foo:
namespace Test
{
class Program
{
static void Main(string[] args)
{
Alpha.Foo foo = new Alpha.Foo(); // Use the full type name
}
}
}
(2):using Instructions
Obviously, using full type names when using types across namespaces is tedious ,C# Nature provides a corresponding solution . For the example above , If you want to be like Alpha Just as simple to use directly in a namespace Foo Express Alpha.Foo, have access to using Instructions to achieve this :
using Alpha; // using Instructions , Import Alpha Namespace
namespace Beta
{
class Program
{
static void Main(string[] args)
{
Foo foo = GetFoo();
}
static Foo GetFoo() { ... }
static void CheckFoo(Foo foo) { ... }
}
}
( By default , because using The scope of the instruction is to use the using The entire document of the directive , therefore using Instructions are required to be placed at the beginning of the file to clearly describe their behavior )
stay using Keyword followed by namespace name , Indicates that in the current file ‘ Use the scope of the specified namespace ’, Or say , Import the scope of the specified namespace into the current file , For convenience , This behavior will be referred to as ‘ Import namespace ’. So the above code uses using Directive import namespace Alpha after , Will use Alpha Scope of action , At this point, the code looks like the following figure :

At this time, the code can be regarded as in Alpha Namespace , So you can use Foo To express Alpha.Foo.
in addition , Multiple can be used at the same time using Statement to import multiple namespaces ,using The order of does not affect program behavior , And the same using The instruction can repeat the declaration ( Although in practice, this behavior is meaningless ). therefore , The following using The effect of the declaration is consistent :
// 1. First Alpha Again Beta
using Alpha;
using Beta;
// 2. First Beta Again Alpha
using Beta;
using Alpha;
// 3. Reuse the same using Instructions , feasible , But it doesn't make sense , The compiler will warn
using Alpha;
using Alpha;
using Beta;
using Beta;
using Beta;
The actual effects of the above import are as follows :

After all, in terms of actual behavior ,using The directive simply imports the scope of the specified namespace , Both sequential and repeated imports should have no effect . We need to pay attention to ,using The directive simply uses the scope , It does not affect the namespaces in the code , in other words , For the following code :
using Alpha;
namespace Beta
{
class Foo { } // Beta.Foo
}
Foo The full type name of is still Beta.Foo, Instead of importing Alpha become Alpha.Beta.Foo.
(2) overall situation using Statement
default using The directive scope is a file , That is to say a using The declaration of the directive only applies to the using This file of the directive is valid . But sometimes a namespace may be frequently used for multiple files , for example System Namespaces are quite common , Many files need to be added additionally using System To import this namespace , This can sometimes lead to a boring experience for coding , So ,C# Provides a method called global using How to import , according to this using The imported namespace will be applied to the entire project , Only need using Add... Before the command global Keyword to import a namespace as a global namespace :
global using System;
Use the above... In any file in a project using After declaration , All files in the project will be imported by default System Namespace . in addition , The syntax defines the overall situation using Must be in normal using Before . It is generally recommended that the global using Write to a single file .
(3)using Alias
using It can also be used to define type aliases :
using Alias = Alpha.Foo;
Alias foo = new Alias(); // Equate to Alpha.Foo foo = new Alpha.Foo()
By using using < Alias > = < Full type name >, You can specify an alias for the specified type , This alias can be used in subsequent code to refer to the type , For example, the above code is Alpha.Foo Type specifies an alias Alias, The compiler encountered a use in the code Alias Type will be replaced by Alpha.Foo. in addition ,using Aliases also apply to generics :
using CatList = System.Collections.Generic.List<Cat>;
CatList cats = new CatList();
using The alias scope is also the entire file , therefore using The alias declaration also requires that it be placed at the beginning of the file to clearly describe its behavior .
3.1.3 global keyword
Introducing global Before keywords , Let's talk about the compiler's process of finding types :
- Find the target type starting with the namespace that uses the type
- If not found in the previous step, try to find using Alias
- If it is not found in the previous step, it is found in using Search in the imported namespace
- If not found in the previous step, search in the parent space of the namespace
- If it is still not found in the parent space, continue to search in the parent space of the parent space , Until you find the global namespace :

Take the specific code as an example :
class Foo { } // Located in the global namespace Foo
namespace Alpha
{
class Foo { } // In namespace Alpha Of Foo
namespace Beta
{
class Foo { } // In namespace Beta Of Foo
class Program // In namespace Beta Of Program
{
static void Main(string[] args)
{
Foo foo = new Foo(); // At this time Foo yes Beta.Foo
}
}
}
}
In the above code Main Methods Foo yes Beta.Foo, The reason is that when the compiler Main Method belongs to Program The namespace to which the class belongs Beta Find the type for the starting point Foo when , stay Beta Next, I found Foo The definition of , So stop looking up , in other words , Will not continue to find Alpha Or in the global namespace Foo. At this point, if you want to use... In the global namespace Foo, You need to tell the compiler that you should start looking directly from the global namespace ( Instead of the current namespace ), You can add... Before the type name by global:: To achieve this :
global::Foo foo = new global::Foo(); // Tell the compiler to start searching from the global namespace , here Foo The one in the global namespace Foo
About global In fact, the keyword has been mentioned above , Here are just some of its practical functions .
3.2 Namespace conflict
(1) The imported namespace has a type name conflict with the current namespace
Sometimes the imported namespace may contain types that conflict with the current namespace , for example :
file 1 Content :
namespace Alpha
{
class Foo { }
}
file 2 Content :
using Alpha;
namespace Test
{
class Foo { }
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo(); // Alpha.Foo still Test.Foo?
}
}
}
file 1 Medium Alpha Namespace defines a Foo object , file 2 Use in using The instruction imports Alpha Namespace , But at the same time in its namespace Test It also defines a Foo, also Main Method is not a full type name , Which one should the above code use Foo? The answer is Test.Foo, That is, under this namespace Foo. The reason is mentioned earlier , When the compiler looks for a type, it will look up from this namespace , At this point, the compiler is in the namespace Test I found that Foo The definition of , Therefore, it will not continue to find Alpha Namespace . If you want to use Alpha Under the Foo, It still needs to use the full type name :
Alpha.Foo foo = new Alpha.Foo();
Note the use of using Invalid alias , The reason is that the compiler ‘ Start with the current namespace to find ’ This behavior has priority over ‘ lookup using Alias ’ High priority .
(2) There is a type name conflict between imported namespaces
Multiple using Type name conflicts may also occur between namespaces imported by directives , For example, the contents of the two files are as follows :
file 1 Content :
namespace Alpha
{
class Foo { }
class Cat { }
}
namespace Beta
{
class Foo { }
class Dog { }
}
file 2 Content :
using Alpha;
using Beta;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat(); // yes Alpha.Cat
Dog dog = new Dog(); // yes Beta.Dog
Foo foo = new Foo(); // Alpha.Foo still Beta.Foo?
}
}
}
file 2 Using two using Instructions are imported into Alpha On Beta Namespace , And in Main Methods use types under these two namespaces . among Cat Only in Alpha Namespace has been defined , Therefore, its type can be confirmed ( Empathy Dog). However, due to the Alpha and Beta At the same time, it defines Foo type , also using The order of does not affect program behavior , The compiler cannot confirm at this time Foo In the end should use Alpha still Beta Namespace . To solve this kind of problem , You also need to use the full type name :
Alpha.Foo foo = new Alpha.Foo();
Beta.Foo foo = new Beta.Foo();
Of course , You can also use using Alias to specify Foo Type represented :
using Foo = Alpha.Foo; // take Foo As Alpha.Foo Another name for
using Foo = Beta.Foo; // Or will Foo As Beta.Foo Another name for
3.3 Special namespaces
3.3.1 static Namespace
static Namespaces are used to simplify member calls to static classes . For example, there are the following static classes :
namespace Hello
{
static class Speaker
{
public static void Say();
}
}
Use this static class in another file :
using Hello;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Speaker.Say();
Speaker.Say();
Speaker.Say();
}
}
}
There is no problem with the above usage , But static classes don't need to be instantiated , And static classes are often just used to organize code . let me put it another way , Sometimes the class name of a static class is not important , It can be omitted . So ,C# Provides a special using Directive allows programmers to omit the class name when calling static class members :
using static Hello.Speaker; // using static + The full type name of the static class
namespace Test
{
class Program
{
static void Main(string[] args)
{
Say();
Say();
Say();
}
}
}
The above code uses using static + The full type name of the static class Import static classes to the current file , It is equivalent to telling the compiler that the code in the current file is also included in the type scope of the static class , It looks like the picture below :

therefore , above Main Method call Say When the method is used , It can be like the code in Speaker Use the same as static classes Say Methods , In a sense , You can think of the static class name as a namespace . in addition , If a method with the same name as that in the static class is defined in the class , The method defined in the class is preferred , At this point, if you want to use the methods in the static class, you still need to use the class name . Method name :
using static Hello.Speaker; // using static + The full type name of the static class
namespace Test
{
class Program
{
static void Main(string[] args)
{
Say(); // It's called Program Class Say
Speaker.Say(); // At this time, only by class name . Method name call
}
static void Say() { ... } // And static classes Speaker Of Say The method has the same name
}
}
3.3.2 Namespaces that act on file scope
The scope of a normal namespace declaration is the code block behind it , But you can also declare namespaces that apply to the entire file range , After declaration, all types defined under this file will be included in this namespace :
namespace Alpha; // take Alpha Namespace declared as file scope
class Cat { }
class Dog { }
Declaring a file scoped namespace is similar to the namespace syntax of a scoped code block , Its biggest advantage is that it reduces the amount of column indentation required when formatting code styles . It should be noted that , Declaring namespaces that act on file scopes has the following restrictions :
- File scoped namespaces can only be declared once , It's obvious
- You can no longer declare a common namespace , in other words , The following code is invalid ,Beta It will not be regarded as Alpha The subspace of :
namespace Alpha;
namespace Beta
{
}
4. Namespace gossip
4.1 Type lookup process
When looking for a type , The compiler will follow the following procedure to find the type :

4.2 Namespace “ name ”
MSDN Namespace is given on Naming suggestions :
.(|)[.][.]
- Add the company name or personal name before the namespace name .
- Use stable at the second level of namespace names 、 Version independent product names .
- Use Pascal nomenclature , And use a period to separate namespace components . however , If the brand name has its own case rules , Follow the brand name .
- Use plural namespace names where appropriate , Exceptions to acronyms .
- The namespace should not be the same as the type name within its scope ( For example, it should not be in the namespace Foo define Foo type ).
Example :
namespace Microsoft.Office.PowerPoint { }
namespace Newtonsoft.Json.Linq { }
4.3 namespace And using Location
C# To use namespace And using There are some requirements for the position where the statement appears , Usually a possible order is as follows :
global using System; // overall situation using Instructions
namespace Alpha; // Namespaces that act on file scope
using Alpha; // using Instructions
using IntList = System.Collections.Generic.List<int>; // using Alias
namespace Beta // Common namespace
{
}
The specific order does not need to be memorized , If the order does not meet the requirements, the compiler will give a prompt .
4.4 Implicit global namespace import
Now new C# After the project , You will find the project csproj There is such a line in the file :
<ImplicitUsings>enableImplicitUsings>
When the project starts ImplicitUsings when , Its function is equivalent to introducing a file for global import of common namespaces for your project , In other words, it is equivalent to adding files with similar contents in your project :
global using System;
global using System.Collections.Generic;
...
This function is applicable to the overall situation using Practical application of instructions , Refer to here , You can also define a file that imports your common namespaces globally , And add it to your project as needed .
4.5 myth
Although in the first example of this article , We are C Language is hypothetical using The function of a sentence is ‘ See that all the following functions have a prefix ’,C# Namespaces in seem to behave exactly the same way . However , Just thinking so will make people mistakenly think that the following code can be compiled :
file 1 Content :
namespace Alpha.Beta
{
class Foo { }
}
file 2 Content :
using Alpha;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Beta.Foo foo = new Beta.Foo(); // look Beta.Foo Adding using Imported Alpha after , Namely Alpha.Beta.Foo 了
}
}
}
In the above documents 2 in , Use using Declaration imported namespace Alpha, And then in Main Method Beta.Foo To express Alpha.Beta.Foo type . It seems that there is no problem , However, this cannot be compiled , It should not be assumed that the compiler will using The imported namespace is combined with the namespace part of the type name ( If you think Alpha and Beta.Foo Of Beta Will be combined into Alpha.Beta), Because it may cause ambiguity , Consider the following code :
file 1 Content :
namespace Alpha.Beta
{
class Foo { }
}
namespace Beta
{
class Foo { }
}
file 2 Content :
using Alpha;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Beta.Foo foo = new Beta.Foo(); // At this time foo yes Beta.Foo still Alpha.Beta.Foo
}
}
}
In the above code Beta.Foo In the end is as Beta.Foo The full type name of the , still Alpha.Beta.Foo Partial type name of ? Obviously this is not clear , To avoid this confusing situation , The compiler does not automatically combine namespaces . It can be said that , If you want to use using Types in the imported namespace , You can only use type names without any namespace elements .
4.6 Use advice
(1) Only one namespace should be declared in a file
(2) Avoid declaring namespaces nested whenever possible , Instead, use a period . Represents the nested relationship of namespaces :
namespace Alpha // Nested declaration namespace
{
namespace Beta
{
}
}
namespace Alpha.Beta // Use . To represent namespace nesting relationships
{
}
(3) Flexible use Using Alias to avoid unnecessary type definition and simplify type name
using IntList = System.Collections.Generic.List<int>; // It means a Int list , But no additional type definitions , It also simplifies the type name
(4) Specify the order of importing namespaces , For example, you can import by namespace name , Or follow the built-in library first → Third party Library → Sequence import of the current project, etc
边栏推荐
- Terraformer importing cloud resources
- RS485(Modbus RTU)工业RFID读写器CK-FR03-A01与PLC三菱FX5U的通讯操作说明
- C# 设置窗体和系统的光标形状
- JSP implementation of performance appraisal system for bank counter business
- VIM secondary replacement
- MySQL advanced statement
- /usr/bin/gzip: 1: ELF : not found /usr/bin/gzip: 3: : not found /usr/bin/gzip: 4: Syntax erro
- 2022工具钳工(中级)操作证考试题库及答案
- 2022 Gansu Province safety officer B certificate test question simulation test question bank and online simulation test
- Terraformer导入云上资源
猜你喜欢

Powerful full text search tool anytxt searcher
![[Clickhouse] the clckhouse view can be inserted but not queried](/img/72/717d70af49be2b1dc2331fe603d106.jpg)
[Clickhouse] the clckhouse view can be inserted but not queried

Variable parameter expression

Recommandation de la Bibliothèque open source de programmation
![[pyhton crawler] regular expression](/img/d3/578514b2d19d5f4ed246a33a333d14.jpg)
[pyhton crawler] regular expression

折叠表达式

Bs-xx-007 registered residence management system based on JSP

代码对比工具,我就用这6个

Distributed file system and enterprise application -- elk enterprise log analysis system

Introduction to long connection
随机推荐
IC fresh Chinese cabbage price of 400000 yuan! Experienced experts who have worked for many years guide you how to choose an offer!
Stochastic dynamic economic dispatching model of wind power (realized by matlab code)
Operating instructions for communication between RS485 (Modbus RTU) industrial RFID reader ck-fr03-a01 and PLC Mitsubishi fx5u
Which exchange is PTA futures on? How can PTA futures be safe?
Kubernetes binary installation (v1.20.16) (V) verifying master deployment
[the path of system analyst] collection of wrong topics of system analyst
SQL must know and know
SAP Spartacus 中的 checkout(结帐) 设计
Customize terrain providers (terrain plugin framework) -04
Bs-xx-007 registered residence management system based on JSP
高比例风电电力系统储能运行及配置分析(Matlab实现)
tampermonkey这玩意如何替换flash播放器为h5播放器?
airtest自动化测试
全球手机市场衰退,连苹果也对iPhone14不抱过高期待
cadence SPB17.4 - allegro - allegro_ free_ viewer
Introduction to long connection
JSTL custom label
Is the brokerage account given by qiniu business school safe? Do you charge for opening an account
SAP Spartacus checkout process uses URL paste to directly jump to delivery mode. Why the page cannot be opened
2022 Gansu Province safety officer B certificate test question simulation test question bank and online simulation test