C#

C# 코딩 규칙

saltdoll 2017. 11. 23. 02:40
반응형

출처: https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/inside-a-program/coding-conventions 


C# 코딩 규칙(C# 프로그래밍 가이드)

C# Language Specification(C# 언어 사양)에서는 코딩 표준을 정의하지 않습니다. 그러나 이 항목의 지침은 Microsoft에서 샘플과 설명서를 개발하는 데 사용됩니다.

코딩 규칙은 다음과 같은 용도로 사용됩니다.

  • 코드를 확인하는 사용자들이 레이아웃이 아닌 내용에 집중할 수 있도록 일관성 있게 표시되는 코드를 만듭니다.

  • 코드를 확인하는 사용자들이 이전 경험을 토대로 한 가정을 통해 코드를 보다 빠르게 이해할 수 있도록 합니다.

  • 코드를 보다 쉽게 복사, 변경 및 유지 관리할 수 있도록 합니다.

  • C# 모범 사례를 제시합니다.

명명 규칙

  • using 지시문이 포함되지 않는 간단한 예제에서 네임스페이스 한정자를 사용합니다. 프로젝트에서 네임스페이스를 기본적으로 가져오는 경우에는 해당 네임스페이스의 이름을 정규화하지 않아도 됩니다. 정규화된 이름은 한 줄에 표시하기가 너무 길면 다음 예제에 나와 있는 것처럼 점(.)으로 분할할 수 있습니다.

    C#
    var currentPerformanceCounterCategory = new System.Diagnostics.
        PerformanceCounterCategory();
    
  • 다른 지침에 맞도록 조정하기 위해 Visual Studio 디자이너 도구를 사용하여 만든 개체 이름을 변경할 필요는 없습니다.

레이아웃 규칙

효율적인 레이아웃에서는 서식을 사용하여 코드 구조를 강조하고 코드를 보다 쉽게 읽을 수 있도록 생성합니다. Microsoft 예제 및 샘플은 다음 규칙을 따릅니다.

  • 기본 코드 편집기 설정(스마트 들여쓰기, 4자 들여쓰기, 탭을 공백으로 저장)을 사용합니다. 자세한 내용은 옵션, 텍스트 편집기, C#, 서식을 참조하세요.

  • 문을 한 줄에 하나씩만 작성합니다.

  • 선언을 한 줄에 하나씩만 작성합니다.

  • 연속 줄이 자동으로 들여쓰기되지 않으면 탭 정지 하나(공백 4개)만큼 들여씁니다.

  • 메서드 정의와 속성 정의 간에는 빈 줄을 하나 이상 추가합니다.

  • 다음 코드에 나와 있는 것처럼 괄호를 사용하여 식의 절을 명확하게 구분합니다.

    C#
    if ((val1 > val2) && (val1 > val3))
    {
        // Take appropriate action.
    }
    

주석 규칙

  • 코드 줄의 끝이 아닌 별도의 줄에 주석을 배치합니다.

  • 주석 텍스트는 대문자로 시작합니다.

  • 주석 텍스트 끝에는 마침표를 붙입니다.

  • 다음 코드에 나와 있는 것처럼 주석 구분 기호(//)와 주석 텍스트 사이에 공백을 하나 삽입합니다.

    C#
    // The following declaration creates a query. It does not run
    // the query.
    
  • 서식이 지정된 별표 블록으로 주석을 묶지 않습니다.

언어 지침

다음 섹션에서는 C# 팀이 코드 예제와 샘플을 준비할 때 따르는 방식에 대해 설명합니다.

문자열 데이터 형식

  • 다음 코드에 나와 있는 것처럼 + 연산자를 사용하여 짧은 문자열을 연결합니다.

    C#
    string displayName = nameList[n].LastName + ", " + nameList[n].FirstName;
    
  • 특히 많은 양의 텍스트를 사용할 때 문자열을 루프에 추가하려면 StringBuilder 개체를 사용합니다.

    C#
    var phrase = "lalalalalalalalalalalalalalalalalalalalalalalalalalalalalala";
    var manyPhrases = new StringBuilder();
    for (var i = 0; i < 10000; i++)
    {
        manyPhrases.Append(phrase);
    }
    //Console.WriteLine("tra" + manyPhrases);
    

암시적으로 형식화한 지역 변수

  • 할당 오른쪽에서 변수 형식이 명확하거나 정확한 형식이 중요하지 않으면 지역 변수에 대해 암시적 형식을 사용합니다.

    C#
    // When the type of a variable is clear from the context, use var 
    // in the declaration.
    var var1 = "This is clearly a string.";
    var var2 = 27;
    var var3 = Convert.ToInt32(Console.ReadLine());
    
  • 할당 오른쪽에서 변수 형식이 명확하지 않으면 var를 사용하지 않습니다.

    C#
    // When the type of a variable is not clear from the context, use an
    // explicit type.
    int var4 = ExampleClass.ResultSoFar();
    
  • 변수 이름을 사용하여 변수 형식을 지정하지 않습니다. 이렇게 하면 형식이 올바르게 지정되지 않을 수 있습니다.

    C#
    // Naming the following variable inputInt is misleading. 
    // It is a string.
    var inputInt = Console.ReadLine();
    Console.WriteLine(inputInt);
    
  • dynamic 대신 var를 사용하지 않습니다.

  • for 및 foreach 루프의 루프 변수 형식을 결정하려면 암시적 형식을 사용합니다.

    다음 예제에서는 for 문에서 암시적 형식을 사용합니다.

    C#
    var syllable = "ha";
    var laugh = "";
    for (var i = 0; i < 10; i++)
    {
        laugh += syllable;
        Console.WriteLine(laugh);
    }
    

    다음 예제에서는 foreach 문에서 암시적 형식을 사용합니다.

    C#
    foreach (var ch in laugh)
    {
        if (ch == 'h')
            Console.Write("H");
        else
            Console.Write(ch);
    }
    Console.WriteLine();
    

부호 없는 데이터 형식

  • 일반적으로는 부호 없는 형식 대신 int를 사용합니다. int는 C# 전체에서 일반적으로 사용되며, int를 사용하는 경우 다른 라이브러리와 보다 쉽게 상호 작용할 수 있습니다.

배열

  • 선언 줄에서 배열을 초기화할 때는 간결한 구문을 사용합니다.

    C#
    // Preferred syntax. Note that you cannot use var here instead of string[].
    string[] vowels1 = { "a", "e", "i", "o", "u" };
    
    
    // If you use explicit instantiation, you can use var.
    var vowels2 = new string[] { "a", "e", "i", "o", "u" };
    
    // If you specify an array size, you must initialize the elements one at a time.
    var vowels3 = new string[5];
    vowels3[0] = "a";
    vowels3[1] = "e";
    // And so on.
    

대리자

  • 대리자 형식의 인스턴스를 만들려면 간결한 구문을 사용합니다.

    C#
    // First, in class Program, define the delegate type and a method that  
    // has a matching signature.
    
    // Define the type.
    public delegate void Del(string message);
    
    // Define a method that has a matching signature.
    public static void DelMethod(string str)
    {
        Console.WriteLine("DelMethod argument: {0}", str);
    }
    
    C#
    // In the Main method, create an instance of Del.
    
    // Preferred: Create an instance of Del by using condensed syntax.
    Del exampleDel2 = DelMethod;
    
    // The following declaration uses the full syntax.
    Del exampleDel1 = new Del(DelMethod);
    

예외 처리의 try-catch 및 using 문

  • 대부분의 예외 처리에서는 try-catch 문을 사용합니다.

    C#
    static string GetValueFromArray(string[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (System.IndexOutOfRangeException ex)
        {
            Console.WriteLine("Index is out of range: {0}", index);
            throw;
        }
    }
    
  • C# using 문을 사용하면 코드를 간소화할 수 있습니다. finally 블록의 코드가 Dispose 메서드 호출뿐인 try-finally 문이 있는 경우에는 using 문을 대신 사용합니다.

    C#
    // This try-finally statement only calls Dispose in the finally block.
    Font font1 = new Font("Arial", 10.0f);
    try
    {
        byte charset = font1.GdiCharSet;
    }
    finally
    {
        if (font1 != null)
        {
            ((IDisposable)font1).Dispose();
        }
    }
    
    
    // You can do the same thing with a using statement.
    using (Font font2 = new Font("Arial", 10.0f))
    {
        byte charset = font2.GdiCharSet;
    }
    

&& 및 || 연산자

  • 예외를 방지하고 불필요한 비교를 건너뛰어 성능을 개선하려면 비교를 수행할 때 다음 예제에 나와 있는 것처럼 & 대신 &&를 사용하고 | 대신 ||를 사용합니다.

    C#
    Console.Write("Enter a dividend: ");
    var dividend = Convert.ToInt32(Console.ReadLine());
    
    Console.Write("Enter a divisor: ");
    var divisor = Convert.ToInt32(Console.ReadLine());
    
    // If the divisor is 0, the second clause in the following condition
    // causes a run-time error. The && operator short circuits when the
    // first expression is false. That is, it does not evaluate the
    // second expression. The & operator evaluates both, and causes 
    // a run-time error when divisor is 0.
    if ((divisor != 0) && (dividend / divisor > 0))
    {
        Console.WriteLine("Quotient: {0}", dividend / divisor);
    }
    else
    {
        Console.WriteLine("Attempted division by 0 ends up here.");
    }
    

New 연산자

  • 다음 선언에 나와 있는 것처럼 암시적 형식이 포함된 간결한 형태의 개체 인스턴스화를 사용합니다.

    C#
    var instance1 = new ExampleClass();
    

    위의 줄은 다음 선언과 동일합니다.

    C#
    ExampleClass instance2 = new ExampleClass();
    
  • 개체를 간편하게 만들려면 개체 이니셜라이저를 사용합니다.

    C#
    // Object initializer.
    var instance3 = new ExampleClass { Name = "Desktop", ID = 37414, 
        Location = "Redmond", Age = 2.3 };
    
    // Default constructor and assignment statements.
    var instance4 = new ExampleClass();
    instance4.Name = "Desktop";
    instance4.ID = 37414;
    instance4.Location = "Redmond";
    instance4.Age = 2.3;
    

이벤트 처리

  • 나중에 제거할 필요가 없는 이벤트 처리기를 정의하는 경우 람다 식을 사용합니다.

    C#
    public Form2()
    {
        // You can use a lambda expression to define an event handler.
        this.Click += (s, e) =>
            {
                MessageBox.Show(
                    ((MouseEventArgs)e).Location.ToString());
            };
    }
    
    C#
    // Using a lambda expression shortens the following traditional definition.
    public Form1()
    {
        this.Click += new EventHandler(Form1_Click);
    }
    
    void Form1_Click(object sender, EventArgs e)
    {
        MessageBox.Show(((MouseEventArgs)e).Location.ToString());
    }
    

정적 멤버

  • ClassName.StaticMember와 같이 클래스 이름을 사용하여 static 멤버를 호출합니다. 이렇게 하면 정적 액세스가 명확하게 표시되므로 코드를 보다 쉽게 읽을 수 있습니다. 파생 클래스 이름을 사용하여 기본 클래스에 정의된 정적 멤버를 정규화해서는 안 됩니다. 이 코드는 컴파일되기는 하지만 가독성이 떨어지며 나중에 파생 클래스와 이름이 같은 정적 멤버를 추가하면 코드가 손상될 수도 있습니다.

LINQ 쿼리

  • 쿼리 변수에 의미 있는 이름을 사용합니다. 다음 예제에서는 Seattle 거주 고객에 대해 seattleCustomers를 사용합니다.

    C#
    var seattleCustomers = from cust in customers
                           where cust.City == "Seattle"
                           select cust.Name;
    
  • 별칭을 사용하여 익명 형식의 속성 이름 대/소문자를 올바르게 표시합니다(파스칼식 대/소문자 사용).

    C#
    var localDistributors =
        from customer in customers
        join distributor in distributors on customer.City equals distributor.City
        select new { Customer = customer, Distributor = distributor };
    
  • 결과의 속성 이름이 모호하면 속성 이름을 바꿉니다. 예를 들어 쿼리에서 고객 이름과 배포자 ID를 반환하는 경우 결과에서 이러한 정보를 Name 및 ID로 유지하는 대신 Name은 고객의 이름이고 ID는 배포자의 ID임을 명확하게 나타내도록 이름을 바꿉니다.

    C#
    var localDistributors2 =
        from cust in customers
        join dist in distributors on cust.City equals dist.City
        select new { CustomerName = cust.Name, DistributorID = dist.ID };
    
  • 쿼리 변수 및 범위 변수의 선언에서 암시적 형식을 사용합니다.

    C#
    var seattleCustomers = from cust in customers
                           where cust.City == "Seattle"
                           select cust.Name;
    
  • 위의 예제에 나와 있는 것처럼 from 절 아래의 쿼리 절을 정렬합니다.

  • 뒷부분의 쿼리 절이 필터링을 통해 범위가 좁아진 데이터 집합에 대해 작동하도록 다른 쿼리 절 앞에 where절을 사용합니다.

    C#
    var seattleCustomers2 = from cust in customers
                            where cust.City == "Seattle"
                            orderby cust.Name
                            select cust;
    
  • 내부 컬렉션에 액세스하려면 join 절 대신 여러 from 절을 사용합니다. 예를 들어 Student 개체 컬렉션이 각각 테스트 점수 컬렉션을 포함하는 경우 다음 쿼리를 실행하면 90점보다 높은 각 점수와 해당 점수를 받은 학생의 성이 반환됩니다.

    C#
    // Use a compound from to access the inner sequence within each element.
    var scoreQuery = from student in students
                     from score in student.Scores
                     where score > 90
                     select new { Last = student.LastName, score };
    

보안

보안 코딩 지침의 지침을 따르세요.

참고 항목

Visual Basic 코딩 규칙
보안 코딩 지침


반응형