Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

13 things C # developers should know

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article describes 13 things that C# developers should know, hoping to help C# developers.

1. Development process

The development process is where errors and defects begin. Using tools can help you solve some problems after release.

Coding standard

Following coding standards allows you to write more maintainable code, especially in a code base written and maintained by multiple developers or teams. For example, FxCop,StyleCop and ReSharper are commonly used tools to implement coding standards.

Developer: before compressing the code, use the tool to carefully check for violations of standards and analyze the results. Using the tool to find code path problems is no less than you might expect.

Code review

Code review and pair programming is a common practice for task developers to review source code written by others. In these ways, we hope to be able to detect the author's errors, such as coding errors or implementation errors.

Code review is a valuable practice, but it relies on humans and is prone to mistakes, so it is difficult to expand.

Static analysis

Static analysis tools analyze code without running it, and look for problems that violate coding standards or have defects without writing test cases. They can effectively find problems, but you need to choose tools that can identify valuable problems and identify valuable problems. C # static analysis tools include Coverity,CAT.NET and Visual Studio code analysis.

Dynamic analysis

Dynamic analysis tools analyze code at run time to help you find defects such as security vulnerabilities, performance, and concurrency issues. It analyzes the code in the context of the runtime environment, so its effectiveness is limited by the test workload. Visual Studio provides several dynamic analysis tools, including concurrency visualizer, IntelliTrace and analysis tools.

Managers / team leaders: leverage development best practices to avoid common pitfalls. Carefully consider the tools available to ensure that they are compatible with your needs and culture.

test

There are many types of tests, such as unit testing, system integration testing, performance testing, and * testing. During the development phase, most tests are written by developers or testers to verify that the application meets its requirements.

Tests are valid only if they run the correct code. It is challenging to maintain the speed of development while implementing functionality and testing.

Development best practices

Invest time in identifying and configuring tools to find code issues you care about without bringing more work to developers. Analysis tools and tests are often run automatically to ensure that developers can locate problems soon after the code has been written.

Locate all diagnostic output as soon as possible-whether it's compiler warnings, standard violations, defects identified by static analysis, or test failures. If all the new diagnoses are negligible, then the role of review increases and developers no longer have to worry about code problems.

Adopting these best practices can help improve code quality, security, and maintainability, developer consistency and productivity, and release predictability.

Concern tools affect consistency, maintainability coding standards, static analysis, consistent spacing for code review, naming and formatting to improve readability and make it easier for developers to write and maintain code. Correct code review, static analysis, dynamic analysis, test code not only need to be syntactically effective, but also in accordance with the developer's intentions and meet the needs of the project. Functional testing verifies that the code meets the requirements, such as correctness, scalability, robustness, and security. Security coding standards, code review, static analysis, dynamic analysis, and test security are very complex issues; any weakness or defect can be exploited. Developer productivity coding standards, static analysis, testing when they have tools to identify errors, developers implement code changes faster. Release predictability coding standards, code review, static analysis, dynamic analysis, testing to simplify later activities, resolve defects and problems as early as possible, and shorten the repair cycle as much as possible.

two。 Type trap

One of the main advantages of C # is its flexible type system; type safety helps to detect errors early. By enforcing strict type rules, the compiler can help you maintain correct coding practices. The C # language and the .NET Framework provide a rich set of types to meet the most common needs. Most developers have a good understanding of common types and their uses, but there are some common misunderstandings and misuses.

More information about the .NET Framework class library can be found in the MSDN library.

Understand and use standard interfaces

Some interfaces involve commonly used C# features. For example, IDisposable allows you to use common resources to handle idioms, such as the "using" keyword. Understanding when to use interfaces allows you to write C # code that is easier to maintain.

Avoid ICloneable-the designer never makes it clear whether the copied object is a deep copy or a shallow copy. Because there is no standard for correctly copying the behavior of objects, it is impossible to use such interfaces effectively.

structure

Try to avoid writing about structures. Treating them as immutable prevents confusion and is safer in shared memory scenarios such as multithreaded applications. Instead, initialize the object when you create the structure, and if you need to change the value, create a new instance.

Learn which standard types / methods are immutable and return new values (for example, string,DateTime) and which are mutable (List.Enumerator).

String

The string can be null, so it is easy to use when appropriate. Equivalence (s.Length = = 0) may throw a NullReferenceException, but the String.IsNullOrEmpty (s) and String.IsNullOrWhitespace (s) functions handle null gracefully.

Tag enumeration

Enumerated types and constant values are identifiers that reveal their meaning and are used to replace magic numbers to make the code more readable.

If you find that you need to create a collection of enumerations, tag enumerations may be a simpler option:

[Flag] public enum Tag {None = 0x0, Tip = 0x1, Example=0x2}

This allows you to easily add multiple tags to the code snippet:

Snippet.Tag = Tag.Tip | Tag.Example

This improves data encapsulation because you don't have to worry about exposing internal collections through Tag property getter.

Equivalent comparison

There are two types of equivalence:

References are equal, which means that two references refer to the same object.

Values are equal, which means that two different objects are equal.

In addition, C# provides a variety of ways to test equivalence. The most common method is to use:

= and! = operator

Virtual Equals method inherited from Object

Static Object.Equals method

Equals method of IEquatable interface

Static Object.ReferenceEquals method

It may be difficult to know whether reference equality or value equality is expected. If you rewrite Equals, don't forget IEquatable, GetHashCode (), as described in MSDN.

Note the effect of untyped containers on overloading. Consider comparing "myArrayList [0] = = myString". The array list element is a compile-time type "object", so using references is equivalent. The C # compiler will warn you of this potential error, but there are many similar cases where the compiler will not warn you about unexpected reference equality.

3. Class trap

Encapsulate your data

Class is responsible for managing data correctly. For performance reasons, they usually cache some results or make assumptions about the consistency of their internal data. Public access to data can affect your ability to cache or make assumptions, potentially affecting performance, security, and concurrency. For example, exposing variable members, such as generic collections and arrays, allows users to modify these structures without your knowledge.

Attribute

Properties give you precise control over how users interact with your objects, except that you control them by accessing modifiers. Specifically, properties enable you to control what happens when reading and writing.

Properties enable you to build a stable API, rewrite data access logic in getter and setter, or provide data binding sources.

Do not and do not let the property acquirer throw an exception to avoid modifying the state of the object. This means that you need a method instead of a property acquirer.

For more information about attributes, see MSDN's property design topic: http: / / msdn.microsoft.com/en-us/library/ms229006 (v=vs.120) .aspx

Use getters carefully because it has side effects. Developers think that member access is a trivial operation, so they often forget to consider the side effects during code review.

Object initialization

You can set properties on newly created objects when you create an expression. Use specific values to create the Class Cde object, and use the Foo and Bar properties:

New C {Foo=blah, Bar=blam}

You can also create an instance of an anonymous type with a specific property name:

Var myAwesomeObject = new {Name= "Foo", Size=10}

Initialization is performed before the constructor runs, ensuring that the field is initialized before entering the constructor. Because the constructor is not yet running, the field initializer cannot reference "this" in any way.

Overspecify input parameters

To help prevent overuse of a particular method, try using the minimum specific type required for the method. For example, consider an iterative List approach:

Public void Foo (List bars) {foreach (var b in bars) {/ / do something with the bar... }}

For other IEnumerable collections, this code works fine, but by specifying List for the parameter, you need the collection to be a List. Select the minimum specific type of parameter (IEnumerable, ICollection, etc.) to ensure the maximum usefulness of the method

4. Generics

Generics are a very effective way to define type-independent structures and algorithms to ensure type safety.

Using generic collections such as List rather than untyped collections such as ArrayList can improve the security and performance of types.

When implementing generic types, you can use the "default" keyword to get default values that cannot be hard-coded into the implementation. Specifically, the default value for numeric types is 0; for reference and nullable value types, the default value is null.

T = default (T); 5. Type transformation

There are two types of conversions conversions. Explicit conversions must be called by the developer, and implicit conversions are applied by the compiler based on context.

Cast description Tree tree = (Tree) obj; use this if obj is of type tree. If obj is not of type Tree, an InvalidCast exception is generated. Tree tree = obj as Tree; use this when you are not sure whether obj is of type Tree. If obj is not of type Tree, a null value will be assigned to Tree. Use this conversion method when necessary because it requires conditional processing of the return value. This extra code may generate more errors, making the code more difficult to read and debug.

When type conversion, you often encounter the following two situations:

The runtime type of an expression is more specific than the type that the compiler can infer. The conversion instructs the compiler to treat the expression as a more specific type. If your assumption is not correct, the compiler will throw the exception code. For example, conversion from an object to a string.

The conversion instructs the compiler to generate code for the value of the associated expression, or throws an exception if it is not. For example, the conversion from double to integer.

Both types of conversions are dangerous. The first type of conversion raises the question, "Why do developers know and compilers don't?" In this case, try to change the program so that the compiler can successfully deduce the correct type. If you think that the runtime type of an object may be more specific than the compile-time type, you can use the "is" or "as" operators.

The second type conversion raises the question, "Why is the operation performed at the beginning, not at the target data type?" If you need a result of type int, it makes more sense to use int than double.

For other ideas, see: http://blogs.msdn.com/b/ericlippert/archive/tags/cast+operator/

When explicit conversion is correct, improve readability, debugging, and testability by using appropriate operators.

6. Abnormal

Exception is not a condition.

Exceptions are not usually applied to control program flow; they represent unexpected situations that you may not be able to recover at run time. If you expect the situation you should deal with, take the initiative to check the situation instead of waiting for an exception to occur.

To properly convert a malformed string to a number, use the TryParse () method; instead of throwing an exception, it returns a Boolean value indicating whether the parsing was successful.

Use exception handling scope

Write code inside catch and carefully process it into blocks. These exceptions no longer exist in executed code. For example:

Frobber originalFrobber = null;try {originalFrobber = this.GetCurrentFrobber (); this.UseTemporaryFrobber (); this.frobSomeBlobs ();} finally {this.ResetFrobber (originalFrobber);}

If GetCurrentFrobber () throws an exception, originalFrobber is still null when finally block is executed

Handle exceptions wisely

Catch only the specific exceptions you are going to handle, and only for specific code snippets. Unless your intention is to simply record and re-throw the exception. Some exceptions may put the application in a state, so you need to avoid handling all instances of exceptions or root class exceptions. It is best if the application has crashed without further damage, rather than trying to recover and cause damage. Your attempt to recover may inadvertently make things worse.

There are some nuances in handling fatal exceptions, especially with regard to how exception security and debuggers are affected when finally block is executed. For more information, please refer to http: / / incrediblejourneysintotheknown.blogspot.com/2009/02/fatal-exceptions-and-why-vbnet-has.html

Use state-of-the-art exception handling to secure the unexpected situation of the handler and expose information to help debug the problem. Use catch blocks carefully to resolve specific situations that could have been safely handled, leaving the highest level of handling for unexpected exceptions.

If you catch an exception, something needs to be done to deal with it. Handling the current exception regardless of other consequences will only make the problem difficult to identify and debug.

It is particularly useful for code that exposes a working API to include exceptions in custom exceptions. Exceptions are part of the visible interface of the method and should be controlled along with parameters and return values. Methods that can cause more exceptions should not be used in maintainable solutions.

Throw and re-throw exceptions

Maintaining the original exception state and stack is a great help for debugging when you want to deal with a caught exception at a deeper level. Careful balance, debugging, and safety considerations are required.

Simply re-throwing an exception is also a good option:

Throw

Or use exceptions as InnerException in the new throw:

Throw new CustomException (..., ex)

Do not explicitly rethrow the caught exception, as follows:

Throw e

This resets the abnormal state to the current line and prevents debugging.

Some exceptions occur outside the context of the code. For these cases, you may need to add event handlers, such as ThreadException or UnhandledException, instead of using catch blocks. For example, a Windows form exception is thrown in the context of a form handler thread.

Data integrity

Exceptions must not affect the integrity of the data model. You need to make sure that your object is in a consistent state-it doesn't violate any assumptions made by the class implementation. Otherwise, by "restoring", you can only mess up your code, which will lead to further damage later.

7. Event

Events and agents assist each other, providing a way for the class to notify the user when the event occurs. Events are similar to fields of delegate type; when objects are created, they are automatically initialized to null.

The value of the event is a multi-level proxy. That is, an agent that can call other proxies in turn. You can assign delegates to events; you can manipulate events through operators such as + = and-=.

Pay attention to the conditions of competition

If events are shared between threads, it is possible that after you check the null and before calling it, another thread will delete all parameters-a NullReferenceException exception will be thrown.

The standard solution is to create local copies of events for testing and invocation. You still need to be careful that any parameters deleted in other threads will work properly when their delegate is called unexpectedly. You can also implement locking to queue operations in a way that avoids problems.

Public event EventHandler SomethingHappened;private void OnSomethingHappened () {/ / The event is null until somebody hooks up to it / / Create our own copy of the event to protect against another thread removing our subscribers EventHandler handler = SomethingHappened; if (handler! = null) handler (this,new EventArgs ();}

For more information about time and racing, please see http: / / blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx

8. Attribute

Properties provide a way to enter metadata for components, classes, and properties with information about their properties. They are often used to provide information to code users, such as code debuggers, test frameworks, and applications. You can define the properties you use, or you can use the predefined properties listed in the table.

Property uses the destination Debugger display debugger display format InternalsVisibleTo member access to expose internal members to specific other classes. Using it, test routines can access protected members. The default value property specifies the default value of the property.

Be careful with the DebuggerStepThrough attribute, which, if applied, can make it difficult to find bug in methods because you can't step through or interrupt them!

9. Debug

Debugging is an important part of any development work. In addition to providing visibility into the regular opacity of the runtime environment, the debugger can enter the runtime environment, and the debugger can lead to different results for the application without the debugger.

Make the exception stack visible

To see the abnormal state of the current frame, add the expression "$exception" to the Visual Studio Watch window. This variable contains the current exception state, similar to what you see in the catch block. Unless you can see the exception state in the debugger, you don't have to actually catch the exception in the code.

Note the side effects in the accessor

If the property you are using has side effects, consider whether you should use properties or debugger settings to prevent the debugger from calling getter automatically. For example, your class might have these properties:

Private int remainingAccesses = 10 * private string meteredData;public string MeteredData {get {if (remainingAccesses-- > 0) return meteredData; return null;}}

The first time you view this object in the debugger, remainingAccesses is displayed as a value of 10 and the MeteredData is displayed as null. If you hover over remainingAccesses, you will see that its value is now 9. The property values displayed by the debugger have changed the state of the object.

10. Optimize

Plan early, measure regularly, and then optimize

Set reasonable performance goals during the design period. During development, focus on correctness rather than subtle optimization. Always measure your effectiveness according to your goals. If you don't reach your goal, you should take the time to optimize the program.

Always use the most appropriate tool to measure performance empirically with repeatability and as close as possible to the actual conditions experienced by the user.

Due to CLR optimization, sometimes inefficient code actually runs faster than efficient code. For example, the CLR optimization covers the loop of the entire array to avoid implicit cell range checking. Developers usually calculate the length before looping the array:

Int [] a_val = int [4000]; int len = axival.Lengthten for (int I = 0; I

< len; i++) a_val[i] = i; 通过将长度放在变量中,CLR可能无法识别模式,并将跳过优化。手动优化违反了直觉,会导致性能较差。 构建字符串 如果你要做很多字符串连接,应该使用System.Text.StringBuilder对象,这样可以避免构建许多临时字符串对象。 对集合使用批处理操作 如果需要创建和填充已知大小的集合,请在创建集合时保留空间,以避免由于重复重新分配而导致的性能和资源问题。你可以使用AddRange方法(如List 中的方法)进一步提高性能: Persons.AddRange(listBox.Items);11. 资源管理 垃圾回收器能够自动清理内存。即使如此,所有一次性资源,也必须妥善处理 - 特别是那些不由垃圾收集器管理的资源。 资源管理问题的常见来源 内存碎片如果没有足够大的连续块的虚拟地址空间,分配将失败。过程限制进程通常访问系统可用的内存和资源的严格子集。资源泄漏垃圾回收器只管理内存。其他资源需要由应用程序正确管理。资源困境依赖于垃圾收集器和终结器的资源在不再使用时,不会变得立即可用。事实上,它们可能永远不可用。 使用try / finally块来确保资源正确释放,或让你的类实现IDisposable,并利用更清洁和更安全的using语句。 using (StreamReader reader=new StreamReader(file)) { //your code here 避免代码中使用垃圾收集器 尽量不要通过调用GC.Collect()干扰垃圾收集器,而应该将重点放在正确释放或处置资源。当测量性能时,如果你能够正确的评估影响,在小心的让垃圾收集器运行。 避免编写终结器 不同于最流行的错误认知,你的类不需要一个Finalizer,仅仅是因为它实现IDisposable!你可以实现IDisposable以使你的类能够在任何所有的复合实例上调用Dispose,但是终结器只应在直接拥有非托管资源的类上实现。 Finalizer主要用于调用interop API,来处理Win32句柄,SafeHandle更容易处理。 你不能推测你的终结器 - 它总是在终结器线程上运行 - 可以安全地与其他对象交互。那些其他对象本身可能已经完成了。 12. 并发 并发和多线程编程是一件很复杂和困难的事情。在向应用程序添加并发之前,请确保你真正了解自己正在做什么 - 有很多细微之处需要了解! 多线程应用程序非常难以推理,并且容易受到诸如通常不影响单线程应用程序的竞争条件和死锁等问题的影响。鉴于这些风险,你应该最后才考虑多线程。如果你必须使用多个线程,请尽量通过不在线程之间共享内存来最小化同步的需要。如果必须同步线程,请使用最高级别的同步机制。 最高级别,这些机制包括: Async-await/Task Parallel Library/Lazy Lock/monitor/AutoResetEvent Interlocked/Semaphore Volatile fields and explicit barriers C#/ .NET中并发的复杂性很难就在这里解释清楚。如果你想要或需要开发一个利用并发的应用程序,请查看详细的文档,如O'Reilly的"Concurrency in C# Cookbook"。 使用volatile 将字段标记为"易变"是高级功能,即使专家也经常误解。C#编译器将确保访问字段具有获取和释放语义; 这不同于确保对该字段的所有访问都处于锁定状态。如果你不知道什么是获取和释放语义,以及它们如何影响CPU级优化,则应避免使用volatile字段。相反,应该使用较高级别的工具,如任务并行库或CancellationToken类型。 利用线程安全的内置方法 标准库类型通常提供方便线程安全访问对象的方法。例如,Dictionary.TryGetValue()。使用这些方法通常使你的代码更清洁,你不需要担心如TOCTTOU or TOCTOU场景等数据竞争的情况。 不要锁定"this",字符串或其他常见的公共对象 当实现在多线程上下文中使用的类时,要非常小心使用锁。锁定此字符串或其他公共对象,会阻止封装锁定状态,并可能导致死锁。你需要防止其他代码锁定你的实现上正在使用的对象; 最安全的做法是使用一个私人的对象成员。 13. 避免常见错误 引用null 不适当的使用null,是编码缺陷的常见来源,可能会导致程序崩溃和其它意外行为。如果你尝试访问一个空引用,以为它是一个对象的有效引用一样 - 例如,通过访问一个属性或方法,运行时将抛出一NullReferenceException异常。 静态和动态分析工具可以帮助你在发布代码之前识别潜在的NullReferenceException异常。在C#中,空引用通常由尚未引用对象的变量引起。对于空值类型和引用类型来说,Null是一个有效值。例如,Nullable ,空委托,取消订阅事件,会在"as"转换,以及在许多其他情况下失败。 每个空引用异常是都一个错误。不应该去捕获NullReferenceException,而应该尝试在使用它们之前测试对象是否为null。这也使得代码更容易被最小化try / catch块读取。 从数据库表中读取数据时,请确保,缺失值可以表示为DBNull对象,而不是空引用。不要指望它们表现的像潜在的空引用。 将十进制值替换为二进制数 浮点数和双精度表示二进制有理数,不是小数有理数,在存储十进制值时必须使用二进制的近似值。从十进制的角度来看,这些二进制近似具有不一致的舍入和精度 - 有时导致算术运算的意外结果。因为浮点运算通常在硬件中执行,硬件条件可能会不可预测地加剧这些差异。 当小数精度非常重要时,使用十进制,就像财务计算等情况。 修改结构 一个常见的错误情况是忘记结构体是值类型的,这就意味着它们被复制了并且通过值来进行传递。假设你有这样的代码: struct P { public int x; public int y; }void M(){ P p = whatever; … p.x = something; … N(p); 有一天,维护者决定将代码重构为: void M(){ P p = whatever; Helper(p); N(p);}void Helper(P p){ … p.x = something; 现在当在M()中调用N(p)时,p具有错误的值。调用助手(p)传递p的副本,而不是p的引用,因此Helper()中执行的变化将丢失。相反,Helper会返回修改的p的副本。 意外的算术 C#编译器保护你出现常量的算术溢出,但不一定是计算值。 忽略保存返回值 与结构体不同,类是引用类型,方法可以修改引用的对象。然而,不是所有的对象方法都实际修改了引用的对象,一些会返回一个新对象。当开发人员调用后者时,他们需要记住将返回值赋给变量,以便使用修改后的对象。在代码审查期间,这种类型的问题通常在会被发现。一些对象,如字符串,是不可变的,所以方法从不修改这些对象。即使如此,开发人员也会通常忘记。 例如,考虑string.Replace(): string label = "My name is Aloysius";label.Replace("Aloysius", "secret"); 代码打印"我的名称是Aloysius",因为Replace方法不修改字符串。 不要使迭代器/枚举器变得无效 不要在迭代时修改集合。 List myItems = new List{20,25,9,14,50};foreach(int item in myItems){ if (item < 10) { myItems.Remove(item); // iterator is now invalid! // you'll get an exception on the next iteration 如果你运行这个代码,一旦循环到集合中的下一个项目时。你会收到一个异常抛出。 正确的解决方案,是使用第二个列表来保存你要删除的项目,然后在删除时迭代该列表: List myItems = new List{20,25,9,14,50};List toRemove = new List();foreach(int item in myItems){ if (item < 10) { toRemove.Add(item); }}foreach(int item in toRemove){ 或者如果你使用C#3.0或更高版本,你可以使用List .RemoveAll。 就像这样: myInts.RemoveAll(item =>

(item < 10))

Attribute name error

When implementing a property, note that the property name is different from the data member used in the class. When accessing properties, it is easy to accidentally use the same name, resulting in infinite recursion.

/ / The following code will trigger infinite recursionprivate string name;public string Name {get {return Name; / / should reference "name" instead.

Be careful when renaming indirect attributes. For example, data binding in WPF specifies the attribute name as a string. If you accidentally change the property name, you will inadvertently create a problem that the compiler cannot protect.

These are 13 things that all C# developers should know.

Knowing 13 things that should be known in C # development will help us to better use C # for development. Of course, we can also use some development tools written in C # when developing. Such as ComponentOne Studio Enterprise, this is a .NET full-function control package focused on enterprise applications, supporting WinForms, WPF, UWP, ASP.NET MVC and other platforms, helping to reduce costs while delivering rich desktop, Web and mobile enterprise applications ahead of time.

Original link: https://dzone.com/refcardz/csharp

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report