I present to your attention the translation of the document " Coding Guidelines for C # 3.0, 4.0 and 5.0 ".The purpose of creating this list of rules is to attempt to set standards for writing C # code that would be convenient and practical at the same time. Of course, we practice what we have created. These rules are one of those standards that underlie our daily work in AvivaSolutions. Not all of these rules have a clear rationale. Some of them are simply accepted as standards.
Static code analyzer VisualStudio (which is also known as FxComp) and
StyleCop can automatically apply many of the encoding and formatting rules by analyzing compiled assemblies. You can configure them so that the analysis is done at compile time or an integral part of continuous or daily assembly. This document simply adds additional rules and guidelines, but its supporting site,
www.csharpcodingguidelines.com, provides a list of code analysis rules, depending on which code base you are working with.
Why should I use it?
Some people perceive the standards of writing code as certain restrictions that limit the freedom of creativity. But nevertheless, this approach has been justified and tested for many years. Why? Because not every developer knows that:
')
- It takes 10 times more time to figure out the code than to change it.
- Not every developer knows about the intricacies of using basic constructs in C #
- Not everyone knows which .NET Framework agreements to adhere to, for example, when using
IDisposable
or LINQ with its deferred execution - Not everyone knows how private solutions to any task can affect performance, security, multi-language support, etc.
- Not every developer will be able to understand the beautiful, but abstract code of another developer.
Basic principles
There are many unobvious things that I came across in my work as a consultant and that deserve mention in at least one recommendation for writing code. Unfortunately, the scope of this manual should be within reasonable limits. However, whatever some novice developers think, if I have not mentioned something in this document, this does not mean that it does not deserve attention.
With this in mind, you should understand that this document is not able to cover all situations that you may encounter. In any case of dispute, you should refer to the basic principles that apply in any situation, regardless of context. These include:
- The Principle of Least Surprise . "The rule of least surprise." You must choose the most obvious solution for your tasks, so as not to confuse other developers and make the code more understandable.
- Keep It Simple Stupid (or KISS). Literally - "Make it easier, stupid." This principle says that to solve the problems posed it is necessary to choose the simplest solution.
- You Ain't Gonne Need It (or YAGNI). "You won't need it." It says: “Work on solving current problems, do not write code just because you think it will be useful to you in the future (can you predict the future?)”
- Don't Repeat Yourself (or DRY). "Do not repeat." This principle encourages you to refrain from duplicating the code and not to forget about the " heuristic rule of three "
Despite the fact that the code may look very good, see if it is understandable to other developers, if it has the behavior that you should expect from it, whether it is trying to solve those problems that may arise in the future. If this is not the case, then it is worth thinking about refactoring.
How do i get started?
- Ask all developers to read this document carefully at least once. This should give them an understanding of what principles it contains.
- Make sure that you always have several printed copies of the short links to this manual.
- Include the most significant rules in your Project Checklist, check for the remaining rules during the Peer Review
- Decide which static analysis rules apply to your project and write them somewhere. For example, publish them on your team TFS site or create a standard Visual Studio rule set.
- Enrich your custom code analysis dictionary with terms, names, and concepts specific to your company or business area. If you do not do this, the static analyzer will display warnings on constructions that will not be included in its internal dictionary.
- Configure VisualStudio to perform a check on following the selected static analysis rules as part of the release assembly. Then they will not interfere with the development and debugging, but can be run when switching to release configuration
- Add the following check points to the project checklist to be sure that the entire new code complies with them, or use the appropriate check-in policy if you want any code to be checked for compliance with the rules before being sent to the repository
- ReSharper has an intelligent code inspector that, with some customization, already supports many of the requirements of this manual. It will automatically highlight any code that does not comply with the naming rules (for example, the naming style Pascal or camel notation), find the dead code and do any other checks. One click of the mouse (or a combination of hot keys) will be enough to fix it.
- ReSharper, among other things, has a File Structure window, which gives an overview of the members of your class or interface and allows you to easily move them with a simple drag and drop.
- Using GhostDoc , you can generate XML comments using hotkeys. The beauty of it is that it allows you to accurately follow the style of MSDN documentation. However, do not abuse this tool and use it only as a starting point.
Why did you create it?
The idea came in 2002 when Vick Hartorg (Philips Medical System) and I was tasked with writing
coding standards for C # 1.0. Since that time, I regularly added, deleted and changed rules based on experience, feedback from colleagues and new plug-ins presented in Visual Studio 2010. In addition, after reading
Robert Martin ’s book
“Clean Code: Creating, Analyzing and Refactoring”, I caught fire with his ideas and decided to include some of them as rules. I would like to note that this document is by no means a replacement for his book. I sincerely recommend reading his book in order to firmly grasp the principles underlying his recommendations. In addition, I decided to supplement the principles of writing code with some design principles. They are too important to ignore, and have a great influence on the attainment of high quality code.
Are these guidelines standards?
This document does not state that projects should strictly adhere to these recommendations. Nor does it state that these recommendations are more important than others. However, we recommend that you yourself decide which recommendations are important, which deviations from the standard can be allowed in the project, who will be a consultant in case of doubt, and what typesetting to use for the source code. Obviously, it is you who must make these decisions before embarking on real work.
To help you choose, I assigned the importance of each recommendation:

- The rule that you should never neglect and which applies to all situations.

- It is strongly recommended to comply with this rule.

- It is recommended to follow this rule, but it does not apply to all situations.
In conclusion, I want to say that there is no need for all the generated code to meet the standards. However, if it is possible to modify the templates used to generate the code, try to ensure that they create code that best complies with these guidelines.
Feedback and Disclaimer
This document was drafted largely due to the great contributions of community members, blog articles, online discussions and many years of development in C #. If you have questions, comments and suggestions, email me at
dennis.doomen@avivasolutions.nl or on Twitter at
http://twitter.com/ddoomen . I will try to regularly review and re-publish this document in accordance with new ideas, experiences and comments.
I want to note that these recommendations only reflect my vision of the correct C # code. Aviva Solutions is not responsible for any direct or indirect damages caused by the application of the standards described in this document.
Permission is granted to copy, adapt and distribute this document and brief references to this manual for non-commercial purposes and for internal use. But you cannot distribute this document, publish or distribute any adapted copies of this document for commercial purposes without prior written permission from Aviva Solutions.
Class design guidelines
AV1000 Class or interface must have a single purpose.

The class or interface must have a single purpose within the system in which it is used. As a rule, a class serves one of the purposes: either it describes a type, for example, email or ISBN (international standard book number), or it is an abstraction of some business logic, or it describes a data structure, or is responsible for interaction between other classes. He should never combine these tasks. This rule is known as the
Principle of Unified Responsibility , one of the principles of SOLID.
Tip : A class with the word “And” in the title is a clear violation of this rule.
Tip : For interaction between classes, use
design patterns . If you fail to apply any of the patterns to the class, perhaps it takes on too much responsibility.
Note : If you create a class that describes a type, you can greatly simplify its use if you make it immutable.
AV1001 Create new class instances using the constructor so that you end up with a completely ready-to-use object.

.
The created object should not need to set additional properties before being used for whatever purposes it is planned to use. Moreover, if the constructor needs more than three parameters (which violates rule AV1561), it is possible that the class takes on too much responsibility (violation of rule AV1000).
AV1003 The interface should be small and focused on solving one problem.

The interface must have a name that clearly describes its purpose or the role it performs in the system. Do not combine loosely coupled elements into one interface just because they belong to the same class. Build interfaces based on the functionality for which the called methods are responsible or on the basis of the specific task that this interface performs. This rule is better known as
Interface Segregation Principle .
AV1004 Use an interface, not a base class, to support multiple implementations.

If you want to set an extension point for your class, set it as an interface, not a base class. You do not want to force users of this extension point to make their own implementations based on a base class that may behave in an undesirable way. However, for their convenience, you can create a default implementation (abstract class) that can serve as a starting point.
AV1005 Use the interface to implement
loose coupling between classes.

Interfaces are a great tool for implementing loose coupling between classes.
- They help avoid bidirectional connectivity.
- They make it easy to replace one implementation with another.
- They allow you to replace an unavailable external service or resource with a temporary stub for use in a non-working environment.
- It allows you to replace the current implementation with a dummy in unit testing.
- Using the framework for the implementation of dependency injection, you can put in one place the logic of class selection depending on the requested interface.
AV1008 Avoid static classes

With the exception of the static classes that are used to create extension methods, static classes very often result in bad code. In addition, they are very difficult, if not impossible, to test in isolation until you resort to some very sophisticated tools.
Note : If you really need a static class, mark it as
static
. In this case, the compiler will block the creation of instances of this class and initialize your class before first accessing it. This will save you from having to use a private constructor.
AV1010 Do not hide inherited items behind the new keyword

This not only contradicts
polymorphism , one of the most important principles of object-oriented programming, but also makes child classes difficult to understand. Consider the following two classes:
public class Book { public virtual void Print() { Console.WriteLine("Printing Book"); } } public class PocketBook : Book { public new void Print() { Console.WriteLine("Printing PocketBook"); } }
In this case, the class will have the wrong behavior that you would expect from it when using it:
PocketBook PocketBook = new PocketBook (); pocketBook.Print ();
Here it is shown that the
Print
method has different behavior depending on whether it is called via a reference to the base class or was called as a method of the derived class.
AV1011 Functions that use the base type must be able to use the subtypes of the base type without knowing it.

In other words, the behavior of inherited classes should not contradict the behavior specified by the base class, that is, the behavior of the inherited classes should be expected for code that uses a variable of the base type. The most well-known example of a violation of this rule is the
NotImplementedExeption
exception, when it occurs when a base class method is overridden.
Note : This principle is also known as the Barbara Liskov substitution principle, one of the
SOLID principles.
AV1013 Do not refer to derived classes from the base class

The presence of dependencies in the parent class on its child classes violates the principles of object-oriented programming and prevents other developers from inheriting from your base class.
AV1014 The object must have limited knowledge of other objects that are not directly related to this object.

If your code resembles the code below, then you are breaking the
Law of Demeter .
someObject.SomeProperty.GetChild().Foo();
An object should not open access to the classes on which it depends, because user objects can incorrectly use properties and methods to gain access to objects behind it. By doing so, you allow the code being called to integrate into one with the class you are using. Thus, you limit the possibility of replacing one implementation with another in the future.
Note : Using a class that implements a
fluid interface (Fluent Interface) may seem like a violation of this rule. But the methods being called simply pass the call context to the next link. Thus, it does not cause controversy.
Exception : When using inversion controls and dependency injection frameworks, it is often required that the dependencies are exposed as public properties. As long as these properties are not used for anything other than the implementation of injection dependencies, I would not consider this as a violation of the rules.
AV1020 Avoid
Bidirectional Dependencies

Bidirectional dependence means that the two classes are aware of each other’s public methods or depend on each other’s internal behavior. Refactoring or replacing one of these two classes requires changes in both classes and may entail a lot of unexpected work. The most obvious solution is to create an interface for one of these classes and use injection dependencies.
Exception : Domain models (Domain Model) used in
domain-based design (Domain Driven Design) may use bidirectional dependencies that describe associations from the real world. In such cases, I try to make sure that they are really necessary, and as far as possible I try to avoid them.
AV1025 Classes Must Have Condition and Behavior

If there are many classes in your repository that serve only to describe the data, then most likely you have several (static) classes that contain a lot of processing logic for this data (see rule AV1008). Use the principles of object-oriented programming as recommended in this section, move your data processing logic to the data it uses.
Exception : The only exception to this rule is the classes used to transfer data between application subsystems, also called
Data Transfer Objects , or classes that serve as a wrapper for method parameters.
Recommendations for designing class members
AV1100 Class properties must be able to be set in any order.

Properties should not depend on other properties. In other words, there should be no difference in what property we set in the first place. For example, first
DataSouse
, then
DataMember
or vice versa.
AV1105 Use method instead of property

Use methods instead of properties if:
- More expensive work than setting the field value
- If the property is a conversion. For example,
Object.ToString
method - If the property returns different values ​​for each call, even if the arguments do not change. For example, the
NewGuid
method will return a new value each time. - If the use of the property causes a side effect. For example, a change in the internal state that is not directly related to the property (this violates the command-query responsibility segregation (CQRS) )
Exception : Filling the internal cache or implementing lazy-loading are good exceptions to this rule.
AV1110 Do not use mutually exclusive properties.

If you have properties that cannot be used at the same time, it means that they are two mutually exclusive concepts. Even if these concepts may have some common logic and state, it is obvious that they have different rules that do not fit together.
, , . .
AV1115 
, ( AV1000), .
AV1125 , ,

(stateful object) – , , . , - , . , – , .
HttpContext.Current
ASP.NET.
HttpContext
. , – (Isolate the Ugly Stuff) — .
AV1130 IEnumerable
ICollection
-

, , , .
IEnumerable
, ,
ICollection
.
: .Net 4.5,
IReadOnlyCollection
,
IReadOnlyList
IReadOnlyDictionary<TKey, TValue>
.
AV1135 , , ,
null

null
, . . ,
null
, ,
string.IsNullOrEmpty()
.
AV1137 ,
, . , , ,
IConfiguration
. , , , . , .
AV1140 , ,

, , ISBN ( ), , , , , . , -. .
AV1200 
, ,
if
, . . , . , .
AV1202 
, , , .
AV1205 ,

,
null
,
ArgumentNullException
ArgumentException
— .
AV1210 
,
Exception
,
SystemException
. .
AV1215 
,
async/await
Task
, :
- ,
async/await
Task
, , - , ,
async/await
Task
,
AV1220 null

, ,
null
. , , , , , ,
null
. , , , .
event EventHandler<NotifyEventArgs> Notify; void RaiseNotifyEvent(NotifyEventArgs args) { EventHandler<NotifyEventArgs> handlers = Notify; if (handlers != null) { handlers(this, args); } }
: , . , :
event EventHandler<NotifyEventArgs> Notify = delegate {};
AV1225 
. , ,
On
. ,
TimeChanged
OnTimeChanged
.
: , , . , .
AV1230
The property change notification event should have a name like PropertyChanged
where the Property
property name with which this event is associated should be changed.Note : If your class has many properties that require corresponding events, try implementing an interface instead INotifyPropertyChanged
. It is often used in the Presentation Model and Model-View-ViewModel patterns .AV1235 Do not send null
as an argument when calling an event
Often an event handler is used to handle similar events from multiple senders. In this case, the argument passed is used to pass the context of the event call. Always send a reference to the context (usually this
) when calling an event. In addition, do not send null
when calling an event if it does not have data. If the event has no data, send EventArgs.Empty
instead null
.Exception : For static events, the argument passed must be null
.AV1240 Use generic constraints if possible.
Instead of casting and converting a type from specific to general and vice versa, use a keyword where
or operator as
to cast an object to a specific type. For example:
class SomeClass {}
AV1250 LINQ- ,

:
public IEnumerable<GoldMember> GetGoldMemberCustomers() { const decimal GoldMemberThresholdInEuro = 1000000; var q = from customer in db.Customers where customer.Balance > GoldMemberThresholdInEuro select new GoldMember(customer.Name, customer.Balance); return q; }
LINQ- ,
q
, , , . , ,
foreach
- , ,
GoldMember
. ,
==
,
GoldMember
. LINQ-,
ToList()
,
ToArray()
.
AV1500 7

, 7 , . , , . , , . , , , , . , .
AV1501 private
,
internal

, , . , public.
AV1502 
, ,
customer.HasNoOrder
, . For example:
bool hasOrders = !customer.HasNoOrders;
, , .
AV1505 
DLL
Company.Component.dll
,
Company
— ,
Component
— , . For example:
AvivaSolutions.Web.Controls.dll
AvivaSolutions.Web.Binding
, .
AvivaSolutions.Web.Binding.dll
.
: , Core . . :
AvivaSolutions.Consulting.Core.dll
.
AV1506 ,

.
AV1507 
: , , .
AV1508 , ,

, . – . – , . For example:
AV1510 using

. , :
var list = new System.Collections.Generic.List<string>();
:
using System.Collections.Generic; var list = new List<string>();
,
using
:
using Label = System.Web.UI.WebControls.Label;
AV1515 «»

, , . For example:
public class Whatever { public static readonly Color PapayaWhip = new Color(0xFFEFD5); public cons tint MaxNumberOfWheels = 18; }
, , . , . For example:
mean = (a + b) / 2;
, .
public class SomeSpecialContainer { public const int MaxItems = 32; public const int HighWaterMark = 3 * MaxItems / 4;
: .
AV1520 var
,

var
, LINQ-
var
. , :
var i = 3;
var
:
var q = from order in orders where order.Items > 10 and order.TotalValue > 1000; var repository = new RepositoryFactory.Get<IOrderRepository>(); var list = new ReadOnlyCollection<string>();
. var
« » .
AV1521 
C VisualBasic, . , .
AV1522 
:
var result = someField = GetSomeMethod();
AV1523 
:
var startInfo = new ProcessStartInfo(“myapp.exe”); startInfo.StandardOutput = Console.Output; startInfo.UseShellExecute = true;
Use object initializer : var startInfo = new ProcessStartInfo(“myapp.exe”) { StandardOutput = Console.Output, UseShellExecute = true };
Instead of creating a collection in this way: var countries = new List<string>(); countries.Add(“Netherlands”); countries.Add(“United States”);
Use the collection initializer : var countries = new List<string> { “Netherlands”, “United States” };
AV1525 Do not make an explicit comparison with true
or false
Comparing a Boolean value with true
or false
- this is usually a bad programming style. As an example: while (condition == false)
AV1530 Do not change the loop variable for
or foreach
inside the loop body.
Updating the loop variable inside the loop body causes the code to become confusing. Especially if the variable changes in more than one place. This rule also applies to the loop foreach
, although after the end of the iteration, the enumerator will detect the change of the collection and will throw an exception. for (int index = 0; index < 10; ++index) { if (some condition) { index = 11;
AV1532 
, , , , . , LINQ-,
from
.
AV1535 if
,
else
,
while
,
for
,
foreach
case

, , :
if (b1) if (b2) Foo(); else Bar();
:
if (b1) { if (b2) { Foo(); } else { Bar(); } }
AV1536 default
switch/case

default
, . , ,
InvalidOperationException
, ,
case
. , .
void Foo(string answer) { switch (answer) { case "no": Console.WriteLine("You answered with No"); break; case "yes": Console.WriteLine("You answered with Yes"); break; default:
AV1537 if-else-if
else

For example:
void Foo(string answer) { if (answer == "no") { Console.WriteLine(" "); } else if (answer == "yes") { Console.WriteLine(" "); } else {
AV1540 return

— , . . AV1500,
return
. , ,
return
, .
AV1545 if-else
()

. , :
bool pos; if (val > 0) { pos = true; } else { pos = false; }
:
bool pos = (val > 0);
Instead:
string result; if (someString != null) { result = someString; } else { result = “Unavailable”; }
Write:
return someString ?? “Unavailable”;
AV1547 
Consider the following example:
if (member.HidesBaseClassMember && (member.NodeType != NodeType.InstanceInitializer)) {
, , . , , , .
if (NonConstructorMemberUsesNewKeyword(member)) {
, , . , .
AV1551 
, . :
public class MyString { private string someText; public MyString(string text) { this.someText = text; } public int IndexOf(string phrase) { return IndexOf(phrase, 0, someText.Length); } public int IndexOf(string phrase, int startIndex) { return IndexOf(phrase, startIndex, someText.Length - startIndex ); } public virtual int IndexOf(string phrase, int startIndex, int count) { return someText.IndexOf(phrase, startIndex, count); } }
MyString
IndexOf
, . , . ,
this()
. , .
: , ,
protected virtual
, .
AV1553 ,

C# 4.0 – AV1551 :
public virtual int IndexOf(string phrase, int startIndex = 0, int count = 0) { return someText.IndexOf(phrase, startIndex, count); }
,
null
. , ,
string
,
list
collections
null
( AV1135). .
: . , .
: , , . .
Eric Lippert for more information.AV1555 Avoid Using Named Arguments
Named C # 4.0 arguments have been created to make it easy to call COM components that are known for offering tons of optional parameters. If you need named arguments to improve the readability of a call for a method, this method most likely does too much and needs to be refactored.The only exception where named arguments improve readability is when the object's constructor is invoked, as in the example below: Person person = new Person ( firstName: "John", lastName: "Smith", dateOfBirth: new DateTime(1970, 1, 1) );
AV1561 ,

,
. , , . - .
AV1562 ref
out

. .
AV1564 ,

:
public Customer CreateCustomer(bool platinumLevel) {}
, , :
Customer customer = CreateCustomer(true);
, , , . .
AV1568 
. , , , , .
AV1570 ,
as

as
,
null
. Failure to comply with this requirement may lead to an exception NullReferenceException
at a much later stage of program execution, if the object does not implement the required interface.AV1575 Do not leave commented out code points.
Never send commented out code to the repository. Instead, use a task tracking system to keep track of what work needs to be done. No one later will guess what this or that block of commented code is for. Has it been temporarily commented out for testing? Was it copied as an example? Should I remove it?Naming Guidelines
AV1701 
, .
- , , . ,
HorizontalAlignment
, AlignmentHorizontal
- .
CanScrollHorizontally
, ScrollableX
( ) - ,
: , , , . Visual Studio ,
.
AV1702 
| | Example |
---|
, | | AppDomain |
Interface | | IBusinessService |
() | | ErrorLevel |
() | | FatalError |
Event | | Click |
| | listItem |
| | MainPanel |
| | MaximumItems |
| | maximumItems |
Read-only | | RedValue |
| | listOfValues |
Method | | ToString |
| | System.Drawing |
Parameter | | typeName |
| | TView |
Property | | BackColor |
AV1704 ,

.
AV1705 
,
g_
s_
. , , . :
_currentUser
,
mUserName
,
m_loginTime
.
AV1706 
,
OnButtonClick
OnBtnClick
. , «i» «q». , «index» «query».
: . ,
UI
UserInterface
.
AV1707 , ,

- , , . ,
GetLength
GetInt
- ,
Enum
, Class
Struct
- , ,
AV1708 ,

:
SearchExamination
( ),
Common
( , )
SiteSecurity
( , ). :
BusinessBinder
,
SmartTextBox
EditableSingleCustomer
.
,
Utility
Helper
. - (. AV1008).
AV1709 
- «»
- , , , . «»
- , . , ,
ISession
, TSession
AV1710 
class Employee {
AV1711 , .NET Framework

.NET , .NET Framework. , . , , , , ,
Add
,
Remove
Count
AddItem
,
Delete
,
NumberOfItems
.
AV1712 ,

, , ,
bool b001 = (lo == l0) ? (I1 == 11) : (lOl != 101);
AV1715 Do not be lazy to give appropriate names to the properties.
- Name properties using nouns, phrases with nouns or, in extreme cases, using phrases with adjectives
- Call a property that has a logical type using affirmative phrases. For example,
CanSeek
instead ofCantSeek
- The names of the properties that have a logical type, try using the prefix
Is
, Has
, Can
, Allows
orSupport
- Try to give the property the same name as its type. When you create a property that has an enumeration type, the property name may be the same as the enumeration type name. For example, if you have an enumeration
CacheLevel
, then a property that returns one of its values ​​should also have the nameCacheLevel
AV1720 , -

-. –
ShowDialog
. , , , .
And
. , , (AV1115).
AV1725 , (), ,

, :
AvivaSolutions.Commerce.Web NHibernate.Extensibility Microsoft.ServiceModel.WebApi Microsoft.VisualStudio.Debugging FluentAssertion.Primitives CaliburnMicro.Extensions
: , , ,
Collections
, .
AV1735 
. :
Click
,
Deleted
,
Closing
,
Minimizing
,
Arriving
.
Search
, :
public event EventHandler<SearchArgs> Search;
AV1737 –ing
–ed
, -

, , ,
Closing
, , , —
Closed
.
Before
After
- .
, , .
Deleting
Deleted
,
BeginDelete
EndDelete
. , :
Deleting
:Delete
: ,Deleted
: ,
AV1738 On

On
, . ,
Closing
,
OnClosing
.
AV1739 -,

-, , , , , .
button.Click += (_, __) => HandleClick();
AV1745 Extentions

, .
Extensions
.
AV1755 Async
TaskAsync

,
Task
, —
Async
. ,
TaskAsync
.
AV1800 Any()
,
IEnbmerable

IEnumerable
,
Count
,
Any()
Count()
, .
Count()
, , .. (,
IQueryable
).
:
IEnumerable
, , AV1130, .NET 4.5 , read-only .
AV1820 async
async
- ,
Task.Run
.
Async
, , , . ,
async
, I/O.
AV1825 Task.Run
, ,
Task.Run
, . , .
AV1830 await/async
Task.Wait
await
, .
Task.Wait
(. AV1835).
AV1835 async/await
:
private async Task<string> GetDataAsync() { var result = await MyWebService.GetDataAsync(); return result.ToString(); }
ASP.NET MVC :
public ActionResult ActionAsync() { var data = GetDataAsync().Result; return View(data); }
. Why?
Because the getter properties Result
will block the stream until the operation async
is completed, but since the method async
will automatically return the result to the original stream, and ASP.NET uses a single-threaded synchronization context, they will continue to wait for each other. A similar problem can also occur with WPF, Silverlight or with C # / XAML Windows Store apps. You can learn more about it here .Recommendations for using the framework
AV2201 Use C # type aliases instead of namespace types. System
For example, use object
instead of Object
, string
instead of, String
and int
instead of Int32
. These pseudonyms were introduced to make primitive types first-class C # members, so use them properly.Exception : When referring to static elements of such types, it is usually customary to use the full CLS name, for example, Int32.Parse()
instead int.Parse()
.AV2205 Carefully specify the names of properties, variables, or fields referencing localized resources. The
recommendations in this section apply to localizable resources, such as error messages and menu text.- Use pascal key notation for resource keys.
- . ,
- -
AV2207 ,

, , .. ,
ConnectionStrings
ConfigurationManager
Settings
, Visual Studio.
app.config
web.config
( - ).
AV2210 
, 4 C# «Treat warnings as errors» ( ). .
AV2215 AssemblyInfo.cs

, , , .. . , , , ,
AssemblyInfo.cs
SolutionInfo.cs
, .
AV2220 LINQ

Instead:
var query = from item in items where item.Length > 0;
System.Linq
:
var query = items.Where(i => i.Length > 0);
LINQ- . , .
AV2221 -

- . , :
Customer c = Array.Find(customers, delegate(Customer c) { return c.Name == “Tom”; });
-:
Customer c = Array.Find(customers, c => c.Name == “Tom”);
:
var customer = customers.Where(c => c.Name == “Tom”);
AV2230 dynamic

dynamic
. (performance bottleneck), .
dynamic
(
Activator
)
Type.GetProperty()
Type.GetMethod()
COM Iterop.
AV2235 async/await
Task
C# 5.0 , , , . . , , :
public Task<Data> GetDataAsync() { return MyWebService.FetchDataAsync() .ContinueWith(t => new Data (t.Result)); }
:
public async Task<Data> GetDataAsync() { var result = await MyWebService.FetchDataAsync(); return new Data (result); }
AV2301
AV2305 public
,
protected
internal

Visual Studio , - . , , , .
AV2306 XML

XML . , / , .
AV2307 MSDN

MSDN, .
:
GhostDoc xml .
AV2310 
, , , , , .
AV2316 ,

,
,
. , , , . , , , .
AV2318 ,
Adding ToDo or some other comment code to a block to keep track of the work that needs to be done may seem like a good decision. But in fact, such comments are not needed by anyone. Use a task tracking system such as Team Foundation Server to track flaws.Recommendations for registration
AV2400 Use general layout rules.
- Keep line lengths within 130 characters
- Use 4 spaces as indents and do not use tabs.
- Insert one space between expressions (for example
if
), as well as keywords. Do not use spaces after (
and before )
. For example:
if (condition == null)
- Add a space before and after operators
(
such as +
, -
, ==
) if
, else
, do
, while
, for
foreach
,- . :
var dto = new ConsumerDto() { Id = 123, Name = “Microsoft”, PartnerShip = PartnerShip.Gold, };
- - . , :
methodThatTakesAnAction.Do(x => {
- LINQ- , :
var query = from product in products where product.Price > 10 select product;
or
var query = from product in products where product.Price > 10 select product;
- LINQ-
from
where
- , . For example:
if (!string.IsNullOrEmpty(str) && (str != “new”))
- , , , ,
#region
using
,
AV2402 
AV2406 
- (
#region
) - read-only
- Developments
. , , . , .
AV2407 #region

#region
, . ,
#region
:
- ( Private Definitions region)
- ( )
The site of the company
, , C# . CodePlex.
www.csharpcodingguidelines.com .
:
- Visual Studio 2010/2012
- ReSharper, 10
- C#
useful links
, , , , .
Code Complete: A Practical Handbook of Software Construction (Steve McConnel) . , - . . , 2004, , , , . , 2009.
The Art of Agile Development (James Shore) . , , Scrum . , .
Applying Domain Driven-Design and Patterns: With Examples in C# and .NET (Jimmy Nilsson) . , - (DDD) (TDD). , , .
Jeremy D. Miller's Blog . , , , . , .
LINQ Framework Design Guidelines . , IQueryable.
Best Practices for c# async/await . , .
.