1. Use properties to replace accessible Fields
1... NET data binding only supports data binding. Using attributes can benefit from data binding;
2. You can use lock to add multi-thread support in the get and set accessors of the attribute.
Ii. readonly and const)
1. const can only be used for primitive types, enumerations, and strings, while readonly can be any type;
2. const will replace it with a specific constant during compilation, so that if both the const and readonly values are used in the reference, the re-change to readonly will change the original design intention, this is the need to re-compile the modified assembly to re-reference the new constant value.
3. const is more efficient than readonly, But it loses the flexibility of applications.
Iii. is and
1. Both types are converted at runtime. as operators can only be used in reference types, while is can use values and reference types;
2. The common practice is to use is to determine the type, and then select to use the as or strong type conversion operator (the conversion defined by operater.
Iv. Replace ConditionalAttribute # if # endif Conditional compilation
1. ConditionalAttribute is only used at the method level. Adding other types and attributes is invalid. # if # endif is not restricted;
2. ConditionalAttribute can be used to add OR (OR) operations for multiple compilation conditions, while # if # endif can be used to add AND [Here it can be completely defined as another separate symbol];
3. The ConditioanlAttribute definition can be placed in a separate method to make the program more flexible.
5. Provide the ToString () method
1. Provide detailed user information in a more friendly manner;
2. Use the IFormatter. ToString () method to provide more flexible customization. If the IFormatProvider and ICustomFormatter interfaces are added, the message output is more meaningful.
Vi. Differences between values and reference types
1. The value type does not support polymorphism. It is suitable for storing data operated by applications, while the reference supports polymorphism and is suitable for defining the behavior of applications;
2. Defining an array as a value type can significantly improve program performance;
3. The value type has a small amount of heap memory fragments, memory garbage, and indirect access time. The returned results in the method are replicated to avoid exposing the internal structure to the outside world;
4. value types are used in the following scenarios: The Role of a type is mainly for data storage; public interfaces are completely defined by the Access attributes of some data members; there will never be child classes; there will never be polymorphism.
VII. The value type should be constant and atomic as much as possible.
1. Make our code easier to write and maintain;
2. Three Methods for initializing constants: construction; factory method; construction of a variable auxiliary class (such as StringBuilder ).
8. Make sure that 0 is valid.
1. The default status of the value type should be 0;
2. The value 0 of the enumeration type should not be invalid. In FlagsAttribute, the value 0 should be valid;
3. If the string is null, an Empty string of string. Empty can be returned.
9. Multiple Representation relationships of equal judgment
1. ReferenceEquals () determines that the reference is equal. Only true is returned if two objects reference the same object;
2. The static Equals () method first references and judges the value type;
3. You can use the rewrite Equals () method to determine the reference type when using the value semantics;
4. When rewriting the Equals () method, you should also override the GetHashCode () method and provide the operater = () operation.
10. Understand the defects of the GetHashCode () method
1. GetHashCode () is only applicable to hashed ** key-defined hash values, such as HashTable or Dictionary;
2. GetHashCode () should follow three rules: two equal objects should return the same hash code; it should be an instance without changing; the hash function should generate a random distribution among all integers.
11. Use foreach loop statements first
1. foreach can eliminate the compiler's checks on the array boundary for the for loop;
2. The loop variable of foreach is read-only and an explicit conversion exists. An exception is thrown when the object type of ** object is incorrect;
3. foreach must use the following ** methods: the public GetEnumberator () method, the IEnumberable interface, and the IEnumerator interface;
4. foreach can bring the benefits of resource management, because if the compiler can determine the IDisposable interface, you can use the optimized try... Finally block;
12. The default field Initialization is better than the value assignment statement
1. By default, field life initializes the value type to 0 and the reference type to null;
2. Multiple initialization of the same object will reduce the code execution efficiency;
3. Put field initialization in the constructor for exception handling.
13. Use the static constructor to initialize static members
1. The static constructor is executed before any methods, variables, or attributes of a class are accessed;
2. static fields will also run before the static constructor, and the static constructor is conducive to exception handling.
14. Use the constructor chain (this problem has been solved with optional parameters in. NET 4.0)
1. Use this to hand over the initialization work to another constructor and use base to call the constructor of the base class;
2. The operation sequence of the Instance type is: Set all static fields to 0; execute static field initializer; execute static constructors of the base class; execute the static constructor of the current type;
Set all instance fields to 0, execute the instance field initializer, execute the appropriate base class instance constructor, and execute the current type of instance constructor.
15. Use using and try/finally statements to clear Resources
GC. SuppressFinalize () can be used in the Dispose () method of the IDisposable interface to notify the Garbage Collector not to terminate the operation.
16. Minimize memory Spam
1. It takes additional processing time to allocate and destroy objects on a stack;
2. Tips for reducing the number of objects to be allocated: Frequently used local variables are promoted to fields. A class is provided to store Singleton objects to express common instances of specific types.
3. Use StringBuilder to perform complex string operations.
17. Reduce packing and unpacking as much as possible
1. Follow the implicit conversion from a type to System. Object, and the value type should not be replaced with System. Object;
2. Using Interfaces instead of using types can avoid packing, namely implementing value types from interfaces and then calling members through interfaces.
18. Implement the standard Dispose Mode
1. When a non-memory resource is used, it must have a Terminator. After the Garbage Collector completes the memory object that has not ended it, it will add the implemented Terminator object to the final queue, the garbage collector then starts a new thread to run the Terminator on these objects. This defensive method is because if the user forgets to call the Dispose () method, the garbage collector always calls the terminator method to avoid Memory leakage caused by the release of unmanaged memory resources;
2. Use IDisposable. the Dispose () method requires four tasks: releasing all unmanaged resources, releasing all managed resources, and setting a status tag to indicate whether the Dispose () method has been executed (); call GC. suppressFinalize (this) cancels the end operation of an object;
3. Add a protected virtual method Dispose () for the type requiring polymorphism. The derived class will release its own task by rewriting this method;
4. In the type that requires the IDisoposable interface, a terminator should be implemented even if we do not need a Terminator.
19. define and implement interfaces better than inheritance types
1. Unrelated types can implement a common interface together, and the Implementation interface is easier than inheritance;
2. The interface is relatively stable. It encapsulates a set of functions in one interface as an implementation contract for other types, and the base class can be expanded over time.
20. discerning interface implementation and virtual method Rewriting
1. When implementing an interface in the base class, the derived class needs to use new to hide the use of the base class method;
2. You can declare the method of the base class interface as a virtual method, and then implement it in the derived class.
21. Use delegate expression callback
1. The delegate object itself does not provide any exception capture, so any multicast delegate call will end the entire call chain;
2. By displaying each delegate target on the call delegate chain, the multicast delegate can be prevented from returning only the output of the last delegate.
22. Use events to define External Interfaces
1. Should be declared as a common event, let the compiler create the add and renmove methods for us;
2. Use the System. ComponentModel. EventHandlerList container to store various event processors. When there are a large number of events in the type, you can use it to hide the complexity of all events.
23. Avoid returning references to internal class objects
1. because access to a value type object creates a copy of the object, defining a value type attribute will not change the internal status of the type object;
2. Constant type can avoid changing the object state;
3. define interfaces to restrict access in a subset so as to minimize the damage to the internal state of the object;
4. define a package object to restrict access to another object;
5. You want the customer code to implement the Observer mode when changing the internal data elements so that the object can verify the changes or make the changes accordingly.
24. Declarative Programming is better than imperative Programming
This avoids the possibility of making mistakes in multiple similar manually written algorithms and provides clear and readable code.
25. Implement the type as serializable as much as possible
1. The types should support serialization instead of UI controls, windows, or forms;
2. When the deserialization attribute of nonserializedattriback is added, you can use the OnDeserialization () method of IDeserializationCallback to load the default value;
3. In version control, you can use the ISerializable interface for flexible control. At the same time, a serialized constructor is provided to initialize objects based on the data in the stream. During implementation, the SerializationFormatter exception permission is required;
4. To create a derived class, you must provide a hook method for the derived class to use.
26. Use the IComparable and IComparer interfaces for sorting
1. The IComparable interface is used to implement the most natural sorting relationship for types. If you overload four comparison operators, You can provide an overloaded CompareTo () method to accept specific types as parameters;
2. IComparer is used to provide a sorting relationship different from that of IComparable, or to provide a sorting relationship that is not implemented by the type itself.
27th. Avoid ICloneable Interface
1. The ICloneable interface is never required for value types. Use the default value assignment operation;
2. For the base class that may need to support the ICloneable interface, you should create a protected replication constructor for it and avoid supporting the IConeable interface.
Avoid forced conversion Operator
Replacing the conversion operator with the constructor can make the conversion work clearer. Due to the temporary objects used after the conversion, it is easy to cause some strange bugs.
29. Use the new modifier only when the new version accumulates and causes problems
Thirty, try to implement CLS compatible assembly
1. To create a compatible Assembly, two rules must be followed: the parameter and return value types used by all public and protected members in the Assembly must be compatible with CLS; any public and protected members incompatible with CLS must have a CLS-compatible alternative;
2. You can use an explicit interface to avoid CLS compatibility type check, and CLSCompliantAttribute does not check the CLS compatibility of Private Members.
. Try to implement short and concise methods
1. the JIT compiler compiles methods in units. methods that are not called are not compiled by JIT;
2. If you replace the code of the Case statement in a long Switch with one method, the time saved by the JIT compiler will multiply;
3. You can use the short and concise method and select a few local variables to obtain the optimized register;
4. The fewer control branches in the method, the more likely the JIT compiler will put variables into registers.
. Try to implement small and high cohesion assembly
1. Put all public classes and shared base classes in some Program sets, and put tool classes that provide functions for public classes into the same program set, package related public interfaces into their own Program sets, and finally process classes distributed horizontally in applications;
2. In principle, two components are created: an assembly that is small and aggregated and has a specific function, and an assembly that is large and wide and contains shared functions.
33. Restriction type visibility
1. Using Interfaces to expose the type function makes it easier for us to create internal classes without limiting their availability outside the Assembly;
2. The fewer public types exposed externally, the more options available for future extension and change implementations.
. Create a large-granularity Web API
This minimizes the transaction frequency and load between machines, and places large operations and fine-grained execution on the server.
35. Rewrite is superior to event Processor
1. If an event processor throws an exception, other processors in the event chain will not be called, but the virtual method to be rewritten will not;
2. Rewriting is much more efficient than the associated event processor. The event processor needs to iterate the entire request list, which consumes more CPU time;
3. events can respond at runtime, providing more flexibility and associating multiple responses to the same event;
4. The traffic rule is to process the event of a derived class, And the rewrite method is better.
. Use. NET runtime properly for Diagnosis
1. System. Diagnostics. Debug \ Trace \ EventLog provides all the tools required to add diagnostic information to the program at runtime. The EventLog provides the portal for applications to be written to System Event Logs;
2. Do not write your own diagnostic database.. net fcl already has the core library we need.
. Use the standard configuration Mechanism
1. The System. Windows. Application class of the. NET Framework defines the attributes for creating a general configuration path;
2. Application. LocalAppDataPath and Application. userDataPath generate the local data directory and user data path;
3. Do not write data in ProgramFiles or Windows directories. These locations require higher security permissions and do not expect users to have write permissions.
38. customization and support for data binding
1. BindingMananger and CurrencyManager implement data transmission between controls and data sources;
2. Advantages of Data Binding: Data Binding is much easier than writing your own code. It should be used outside the scope of text data items-other display attributes can also be bound; check related data sources that can process synchronization of multiple controls for Windowos Forms data binding;
3. When the object does not support the required attributes, You can shield the current object and add an object to support data binding.
. Use. NET for verification
1. There are five controls in ASP. NET to verify the validity. You can use CustomValidator to derive a new class to add your own authenticator;
2. For Windows verification, the Child System. Windows. Forms. Control. Validating needs to write an event processor.
40. Select appropriate ones as needed **
1. arrays have two obvious defects: they cannot be dynamically adjusted; it is time-consuming to adjust the size;
2. ArrayList combines the features of one-dimensional arrays and linked lists. Queue and Stack are special arrays built on an Array;
3. When the program adds and deletes items more flexibly, it can make a more robust ** type. When creating a simulated ** class, the indexer and IEnumberable interfaces should be implemented for it.
Forty-one, DataSet is better than custom Structure
1. DataSet has two disadvantages: The Interaction Between DataSet and non-. NET code using the XML serialization mechanism is not very good; DataSet is a very common container;
2. Strong DataSet breaks more design rules, and the development efficiency is much higher than the design that you write.
. Simplified reflection using features
By designing and implementing feature classes, developers are forced to use them to declare types, methods, and attributes that can be dynamically used, which can reduce runtime errors of applications and improve user satisfaction of software.
Forty-three, avoid excessive use of reflection
1. The parameters and return values used by the Invoke members are both System. Object. type conversion is performed at runtime, but problems may become more likely;
2. interfaces allow us to get a clearer and more Maintainability System. Reflection is a very powerful late binding mechanism ,. NET Framework uses it to bind data between Windows controls and Web controls.
Forty-four. Create specific exception classes for the Application
1. The only reason why different exception classes are required is that users can easily adopt different methods for different errors when writing catch processors;
2. When there may be different repair actions, we should create a variety of different exception classes by providing all constructors supported by the exception base class, you can create full-featured exception classes for applications. Using the InnerException attribute, you can save all error messages generated by lower-level error conditions.
45. Priority should be given to exceptional security
1. Strong exceptions ensure the best balance between recovering from exceptions and simplifying Exception Handling. operations are interrupted due to exceptions and the program status remains unchanged;
2. Make a defensive copy of the data to be modified and modify the defensive copy of the data. The intermediate operation may cause exceptions and exchange temporary copies with the original object;
3. The Terminator, Dispose () method, and the target method bound to the delegate object should ensure that they do not throw an exception under any circumstances.
46. Minimal interoperability
1. There are three costs for interoperability: Data enumeration costs between managed and unmanaged stacks, and switching costs between managed and unmanaged code, development work for developers dealing with hybrid environments;
2. Using the blittable type in interop can effectively replicate back and forth in hosted and unmanaged environments without being influenced by the internal structure of the object;
3. Use the In/Out feature to ensure the most appropriate and unnecessary multi-copy, and improve performance by declaring how data is listed;
4. Use COM Interop to implement interoperability with COM components in the simplest way. Use P/Invoke to call Win32 APIs, or use the/CLR switch of the C ++ compiler to mix hosted and unmanaged code;
Forty-seven, security code first
1. Avoid access to unmanaged memory as much as possible. Isolated storage cannot prevent access from managed code and trusted users;
2. When running an assembly on the Web, you can consider using isolated storage. When some algorithms really require higher security licenses, you should isolate those codes in a separate assembly.
Forty-eight, Master related tools and resources
1. Use NUnit to create an automatic unit test (integrated in VS2010 );
2. The FXCop tool obtains the IL code in the Assembly, compares it with the cross-family encoding rules and best practices, and finally reports the violation;
3. ILDasm is an IL Disassembly tool that helps us understand details;
4. Shared Source CLI is an implementation Source code that contains the. NET Framework kernel and the C # compiler.
2.0 prepare for C #4.0 (this rule is meaningless now, after all, it has reached)
50. Understand ECMA standards