Static is a modifier that declares a static field, a static method, or a static class. A field that uses static declarations belongs to the type itself and does not belong to any field, and the declared class also has some special features, such as not being instantiated, inheriting, and so on. In an popularized language, a static field is declared only once, even if more than one type instance is created, and belongs to the type. It is accessible across all class instances. You can think of a static field as a global variable of type.
I will use the static field in some scenarios, most of which are function/method modifiers or simple singleton patterns. I personally think that the static function is similar to the C function (method), while the general functions address the instance method. The static function is independent of the instance, and more shows a non-correlation. On a field, the static modifier is seldom used. Unless the internal instance requires a temporary count, or another type of instance object field that has no status.
Recently, considering the design of a serial communication decoration class (based on SerialPort, System.IO.Port), to expand the functions of serialport, such as frame integrity check, timeout detection and retransmission. Before I started working, there were some basic implementations. Instead of focusing on the functionality of adorners, this class creates instances with simple factory functions and maintains a list of name-based instances internally. After each opening of a serial port, the list will be in the form of <Key,Value>, in memory maintained a serial port of the device list.
Public classserialportdecorator:idisposable {Static Publicdictionary<string, serialconn> _portdict =Newdictionary<string, serialconn>(); PrivateSerialPort _serialport =NULL;
/// <summary> ///Class for Serial Connection to a Comm port. /// </summary> /// <remarks> ///This class should is thread safe and non blocking. It has a modes, one where///A reply is expected (would callback a delegate with response) and one where no///reply is expected. More complex handling of reply and expected response are handled///By the caller. /// </remarks> /// <param name= "Portnamein" ></param> /// <returns></returns> Public StaticSerialconn Getserialconn (stringPortnamein) { Lock(_staticlockobj) {//TODO Validate the PortName if(!_portdict.containskey (Portnamein)) {Serialconn SC=NewSerialconn (); Sc. Initialize (Portnamein); _portdict.add (Portnamein, SC); } return_portdict[portnamein]; } }
It is really tricky to maintain such a state through static fields. I felt a little surprised because I never did. Of course, this does not mean that this is not a good way to achieve. My question has the following points:
- The list of open devices is not a function/concept of the adornment class, the device list belongs to the entire app or serial management center, or other logical concepts.
- You can only provide a list of open or registered serial ports, but not a list of open serial ports, even if the serial list is present. If you need to look at the enumeration serial port, it is obviously not.
- If the external need to know the current list of devices, through the serialportdecorator._portdict to achieve the goal is too strange.
In the MSDN C # Programming Guide, there is a static sample code:
/** * To illustrate static members, see a class that represents a company employee. Suppose the class contains a method for counting employees and a field that stores the number of employees. This method and field are not part of any instance employees, but belong to the company class. Therefore, they should be declared as static members of this class. Example This example reads the name and ID of the new employee, adds an employee counter, and displays information about the new employee and the number of new employees. For the sake of simplicity, the program reads the current number of employees from the keyboard. In the actual application, this information should be read from the file. c#***/ Public classemployee4{ Public stringID; Public stringname; PublicEmployee4 () {} PublicEmployee4 (stringNamestringID) { This. Name =name; This. ID =ID; } Public Static intEmployeecounter; Public Static intAddEmployee () {return++Employeecounter; }}
"The method and the field are not part of any instance employees, but belong to the company class. This phrase indicates the semantics of the static field. Based on this, for the question 1 noncommittal.
With regard to question 2, enumerating the list of disconnected serial ports is clearly a different semantics. This content cannot be provided using the static field, nor is it suitable for decoration classes. Proposed, just to illustrate the requirements of the environment. If there is really such a need, the static field is obviously not appropriate. To some extent, the application scenario of static is pointed out-the semantics is single and definite.
Question 3 is very important. In the MSDN example above, the static field employeecounter just to generate an add-on ID. Although it belongs to the company, it only serves the employee number. Real-world applications do not query the number of employees by querying the ID, typically generating sequence IDs only in batch environments or query results. From this example, I think the scope of the static field should be limited to the class that contains it.
For the discussion of the question-and-offer, I would like to say that the application scenarios and capabilities of the static field have semantic limitations. The static field is semantically not part of the current class and belongs to the anonymous owner of the current noun. In use, it is best to use it only in its own class, without exceeding the class scope.
That's just my personal opinion.
It is not a good idea to maintain state through a static field