Enumeration types undoubtedly bring great convenience to our development, smart sensing +CodeReadability gives us enough reason to use it in projects. However, improper use of enumeration types also has a gentle trap, which is hard to find.
The reason for this is that project a is a public base class, and many projects will reference it. Project B will reference project A. However, because Project B is rarely used and has stable functions, therefore, the DLL file of Project B is generally not uploaded during deployment. However, a sudden error occurred in Project B A a few days ago. The error "the database connection corresponding to the business type cannot be found" was reported ". There is no problem with local debugging project B, but there is an error online. I uploaded the DLL of Project B again, which is amazing. I felt a little strange. I didn't change it at all. Just re-upload the DLL. Why? There is no love for no reason and no error for no reason. The gentle enumeration trap helps me find the answer. The root cause of the question is the enumeration type change in Project.
We can find the answer in the following example. Projecta is a basic class library shared by many projects. projectb adds a reference to projecta, but the two are not in the same solution, when updating projecta, the DLL file of a will be placed under the bin directory of B.
Project code example
Namespace Projecta
{
/// <Summary>
/// Business type
/// </Summary>
Public Enum Businesstype
{
Userread,
Userwrite,
Productread,
Productwrite
}
Public Class Dbhelper
{
/// <Summary>
/// Obtain the connection string based on the business type
/// </Summary>
Public Static String Getconnectstring (businesstype BT)
{
String Connectstring = String . Empty;
Switch (BT)
{
Case Businesstype. userread:
Connectstring = " Userread " ;
Break ;
Case Businesstype. userwrite:
Connectstring = " Userwrite " ;
Break ;
Case Businesstype. productread:
Connectstring = " Productread " ;
Break ;
Case Businesstype. productwrite:
Connectstring = " Productwrite " ;
Break ;
Default :
Connectstring = " Userread " ;
Break ;
}
Return Connectstring;
}
}
}
After Project B adds a reference to project a, its code is as follows.
Project code example
Using Projecta;
Namespace Projrctb
{
Public Class B
{
Public Static Void Getuser (businesstype BT)
{
// Select an appropriate database based on businesstype to obtain data
String Connectstring = Dbhelper. getconnectstring (BT );
Console. writeline (connectstring );
}
}
}
After executing projrctb. B. getuser (businesstype. productread), there is no doubt that "productread" is output, which is consistent with our expectation.The business type is extended. To add the comment type to businesstype, the modified Code is as follows.
Code example after project ta business type Extension
Namespace Projecta
{
/// <Summary>
/// Business type
/// </Summary>
Public Enum Businesstype
{
Commentread,
Commentwrite,
Userread,
Userwrite,
Productread,
Productwrite
}
Public Class Dbhelper
{
/// <Summary>
/// Obtain the connection string based on the business type
/// </Summary>
Public Static String Getconnectstring (businesstype BT)
{
String Connectstring = String . Empty;
Switch (BT)
{
Case Businesstype. commentread:
Connectstring = " Commentread " ;
Break ;
Case Businesstype. commentwrite:
Connectstring = " Commentwrite " ;
Break ;
Case Businesstype. userread:
Connectstring = " Userread " ;
Break ;
Case Businesstype. userwrite:
Connectstring = " Userwrite " ;
Break ;
Case Businesstype. productread:
Connectstring = " Productread " ;
Break ;
Case Businesstype. productwrite:
Connectstring = " Productwrite " ;
Break ;
Default :
Connectstring = " Userread " ;
Break ;
}
Return Connectstring;
}
}
}
Regenerate projecta and deploy its DLL to the bin directory of projectb. Will the execution of projrctb. B. getuser (businesstype. productread) still get the expected results?? The answer is no. After execution, the result is "userread", which is not the "productread" type we want.Why is this happening?
The enumerated value is essentially an integer. After the code is compiled, only the integer of this enumeration is retained in the DLL, but not the enumerated variable name. If the enumeration itself changes, for example, if two items are inserted before the enumeration businesstype, the values of the enumerated variables will change (if not the specified values are not displayed ). At this time, if only the enumeration itself is re-compiled, and projectb is not compiled to reference the enumeration, the problem may occur because the enumerated type represented by the integer has changed.The solution to this problem is to display the value of the specified enumerated variable when creating the enumeration, and do not change the value of the enumerated variable when extending and modifying the enumeration type.The following code adds commentread = 4 and commentwrite = 5 to the business type, instead of the previous business type userread = 0, in this way, you do not need to re-compile project TB in a timely manner during the extension type, and the above problems will not occur.
Display the value of the specified enumerated variable
/// <Summary>
/// Business type
/// </Summary>
Public Enum Businesstype
{
Commentread = 4 ,
Commentwrite = 5 ,
Userread = 0 ,
Userwrite = 1 ,
Productread = 2 ,
Productwrite = 3
}
The essence of the problem is that the variable name is replaced directly with the variable value during compilation. Not only does the enumeration type have this problem, but constants also have this problem. If the constant value is updated, without compiling a project that references a constant, the modification of a constant value is invalid for the project that references it. Therefore, it is recommended that you replace a constant with a fixed value (such as the circumference rate ), you can use readonly to replace constants.
If you do not see a similar problemArticleIt is difficult to find the answer to this question. Writing it out is a kind of improvement for yourself, and I hope it can help my friends who have encountered similar problems.