C#編碼規范


記錄 編碼約定 學習過程。

 

命名空間約定

如果沒有使用using指令,項目也沒有默認導入合適的命名空間,訪問這些命名空間或者類型時,則需要“完全限定名稱”。

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args) 
        {
            // 在這里System.Diagnostics是“完全限定名稱”
            var traceSource = new System.Diagnostics.TraceSource("");
        }
    }
}

如果使用了Using指令,則不需要“完全限定名稱”。

using System.Diagnostics;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {            
            var traceSource = new TraceSource("");
        }
    }  
}

 

代碼布局約定

  1. 不輕易更改編輯器的設置,通常使用默認的,特別是格式設置和制表符。
  2. 每行一條語句,每行一個聲明。
    string[] strs = new string[] { "AA","BB","CC"};
    string str = "hello";
    int num = 4;
    if (num == 9)
    {
    
    }
  3. 一行寫不完的語句,斷行寫則需要縮進一個制表符位,除了起頭的第一行,后面無論再斷多少行都是一個制表符位。
    string[] strs = new string[] { "AA","BB","CC"};            
    var query = strs.Where(x => x.Length == 2 && x.Contains("B")).
        Select(x => new { Name = x, Age = 8 });
  4. 屬性和方法之間至少一個空行
    public int MyProperty { get; set; }
    public int MyProperty1 { get; set; }
    
    void Test()
    {
    
    }
  5. 使用括號突出表達式的字句。
    int val1 = 1;
    int val2 = 3;
    int val3 = 4;
    
    if ((val1 > val2) && (val1 > val3))
    {
        
    }
    

注釋約定

單獨的行,而非代碼末尾;大寫字母開頭,斷行換小寫;句點結束注釋文本;注釋和文本之間留一個空格。

不要在注釋周圍創建格式化的星號塊???沒看懂。

下面放一段ILSpy源碼

/// <summary>
/// Sets the value of a dependency property on <paramref name="targetObject"/> using a markup extension.
/// </summary>
/// <remarks>This method does not support markup extensions like x:Static that depend on
/// having a XAML file as context.</remarks>
public static void SetValueToExtension(this DependencyObject targetObject, DependencyProperty property, MarkupExtension markupExtension)
{
    // This method was copied from ICSharpCode.Core.Presentation (with permission to switch license to X11)
    
    if (targetObject == null)
        throw new ArgumentNullException(nameof(targetObject));
    if (property == null)
        throw new ArgumentNullException(nameof(property));
    if (markupExtension == null)
        throw new ArgumentNullException(nameof(markupExtension));
    
    var serviceProvider = new SetValueToExtensionServiceProvider(targetObject, property);
    targetObject.SetValue(property, markupExtension.ProvideValue(serviceProvider));
}

 

隱式類型var

當明顯可以從賦值右側推導左側變量類型時,使用var。當精確的類型不太重要時,使用var。

var var1 = "This is clearly a string.";
var var2 = 27;
var var3 = Convert.ToInt32(Console.ReadLine());

右側類型不明確時,則可以聲明一個明確的類型。

using System;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            string test = GetObject(2);
            int test1 = GetObject(1);
            decimal test2 = GetObject(3);
        }

        static dynamic GetObject(int x)
        {
            switch (x)
            {
                case 1:return 2;
                case 2:return "";
                default:return 8m;
            }
        }
    }   
}

在for循環使用var,下面的i分別推導為int、decimal。

for (var i = 0; i < 10000; i++)
{               
}

for(var i = 0m; i < 10m; i = i + 0.1m)
{
}

在foreach中不建議使用var。

DataTable dataTable = new DataTable();
// 枚舉值:EnumerableRowCollection<DataRow>,可以推row為DataRow。
foreach (var row in dataTable.AsEnumerable())
{

}
// 雖然可以推,但聲明明確的類型會讓代碼更加清晰,因為無法在枚舉泛型類型里明顯看出當前row的類型。
foreach (DataRow row in dataTable.AsEnumerable())
{

}
// 枚舉值:DataRowCollection,不聲明明確類型row則為object?,因此需要聲明明確的類型。
foreach (DataRow row in dataTable.Rows)
{

}

符號類型

使用時,符號類型優先於無符號類型。short、int、long。 ushort、uint、ulong。

數組

使用間接的語法聲明數組

// 這時候,無法從右側推導變量類型。
string[] vowels1 = { "a", "e", "i", "o", "u" };

// 可以推導,左側使用var
var vowels2 = new string[] { "a", "e", "i", "o", "u" };

var vowels3 = new string[2];
vowels3[0] = "a";
vowels3[1] = "e";

委托

使用簡短的語法為委托賦值。

static void Main(string[] args)
{            
    Del exampleDel2 = DelMethod;
    var del3 = new Del(DelMethod);
}

public delegate void Del(string message);

public static void DelMethod(string str)
{
    Console.WriteLine("DelMethod argument: {0}", str);
}

Using

如果使用try...finally...,且在finally只有釋放資源的代碼,考慮替換成using,using會自動調用Dispose方法。

Font font1 = new Font("Arial", 10.0f);
try
{

}
finally
{
    font1.Dispose();
}

using(Font font=new Font("Arial", 10.0f))
{

}

New運算符

能推導類型使用var,對象實例的構造函數沒有參數則不必調用構造函數。

// 不必使用new ExampleClass()
var instance3 = new ExampleClass
{
    Name = "Desktop",
    ID = 37414,
    Location = "Redmond",
    Age = 2.3
};

var instance4 = new ExampleClass();
instance4.Name = "Desktop";
instance4.ID = 37414;
instance4.Location = "Redmond";
instance4.Age = 2.3;

事件處理

在事件比較簡短、且只使用一次的情況下,可以考慮使用lambda表達式。

public Form1()
{
    InitializeComponent();
    
    this.Click += (s, e) =>
    {
        MessageBox.Show(s.ToString());
    };
}

 靜態成員

 派生對象時,不建議添加和基類具有相同名稱的靜態成員。

using System;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            ExampleClass2.Test();
        }      
    }

    class ExampleClass
    {
        public static void Test()
        {
            Console.WriteLine("調用ExampleClass Test");
        }
    }
    class ExampleClass2:ExampleClass
    {
        // 同名容易引起混亂,隱性覆蓋了ExampleClass的Test方法。
        public static void Test()
        {
            Console.WriteLine("調用ExampleClass2 Test");
        }        
    }

    class ExampleClass3 : ExampleClass
    {
        // 使用new,說明有意覆蓋。
        public new static void Test()
        {

        }
    }
}

 Linq查詢表達式

 匿名類型遵循Pascal大小寫格式(與駱駝命名法類似,駱駝命名法是首字母小寫,而Pascal帕斯卡命名法是首字母大寫)。

var localDistributors = from customer in customers
                        join distributor in distributors on customer.City equals distributor.City
                        select new
                        {
                            Customer = customer,
                            Distributor = distributor,
                            CustometorId = customer.ID
                        };

在查詢變量和范圍變量的聲明中使用隱式類型化,雖然查詢變量沒有明確標有var關鍵字,但確實隱式化了。

using System;
using System.Linq;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            var customers = new System.Collections.Generic.List<Customer>();
            var distributors = new System.Collections.Generic.List<Distributor>();

            var localDistributors = from customer in customers
                                    join distributor in distributors on customer.City equals distributor.City
                                    select new
                                    {
                                        Customer = customer,
                                        Distributor = distributor,
                                        CustometorId = customer.ID
                                    };

        }
    }

    internal class Distributor
    {
        public object City { get; internal set; }
    }
    internal class Customer
    {
        public object City { get; internal set; }
        public object ID { get; internal set; }
    }
}

對其from字句下面的查詢語句。

// 第一種:from語句不和聲明變量同一行,則在下一行縮進一個制表符。
var
localDistributors = from customer in customers join distributor in distributors on customer.City equals distributor.City select new { Customer = customer, Distributor = distributor, CustometorId = customer.ID };
// 第二種:from語句和聲明變量同一行
var localDistributors = from customer in customers join distributor in distributors on customer.City equals distributor.City select new { Customer = customer, Distributor = distributor, CustometorId = customer.ID };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM