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 코딩 규칙
보안 코딩 지침


반응형
도움이 되셨다면 하트모양의 "♡ 공감"을 눌러주시면 큰 격려가 됩니다.
(로그인하지 않으셔도 가능)