일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- IValueConverter
- coding-test
- convert
- nullable
- mysql
- File
- string
- chashtag
- windows
- Process
- git
- windows10
- Coding
- logging
- log
- 코딩테스트
- WPF
- commit
- .net
- Github
- Binding
- programmers
- csharp
- C#
- ListView
- algorithm
- Microsoft
- dotNET
- tls
- Visual Studio
Archives
- Today
- Total
CHashtag
[C#] 코딩 규칙 (Coding Convention) 본문
반응형
안녕하세요.
오늘은 C#개발을 할 때에 지켜야 할 규칙에 대해 알려드리려 합니다.
오늘 알려드릴 내용은 "권장사항" 입니다.
아래 코딩 규칙이 회사, 팀에서 사용하고 코딩 규칙과 다르다면 따르지 않는것을 추천합니다.
코딩 규칙이 존재하는 이유는 여러 사람이 일관성있는 코드를 작성할 수 있게 돕고, 그로인해 코드 가독성을 높이기 위함임을 꼭 기억하기시 바랍니다.
일관성 있는 코드 작성 -> 가독성 올라감 -> 코드 리딩 및 이해가 빠름 -> 개발시간 단축 및 리팩토링 용이
(아래 몇몇 규칙중에서는 성능을 높여주는 규칙도 포함되어 있습니다.)
오늘 게시글은 마이크로소프트 공식 문서를 참고하여 예제를 추가한 것입니다.
관련해 더 자세하고 정확한 내용은 원문을 참고해주시기 바랍니다.
(docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/inside-a-program/coding-conventions)
1. 레이아웃 규칙
1-1. 문을 한 줄에 하나씩만 작성합니다.
MessageBox.Show("한줄에 하나씩");
MessageBox.Show("코드를 작성합니다.");
1-2. 선언을 한 줄에 하나씩만 작성합니다.
string text1 = "선언은 한 줄에 하나씩";
string text2 = "선언은 한 줄에 하나씩";
1-3. 연속 줄이 자동으로 들여쓰기되지 않으면 탭 정지 하나(공백 4개)만큼 들여씁니다.
bool canEat = true;
if(canEat)
{
MessageBox.Show("4칸을 들여씁니다.");
}
1-4. 메서드 정의와 속성 정의 간에는 빈 줄을 하나 이상 추가합니다.
// Tomato 속성과 GetTomato 메서드 정의 사이에 빈 줄을 추가합니다.
public Tomato Tomato { get; set; }
public Tomato GetTomato()
{
return this.Tomato;
}
1-5. 괄호를 사용하여 식의 절을 명확하게 구분합니다.
if ((val1 > val2) && (val1 > val3))
{
MessageBox.Show("괄호를 사용하면 가독성이 높아집니다.");
}
2. 주석 달기 규칙
2-1. 코드 줄의 끝이 아닌 별도의 줄에 주석을 배치합니다.
MessageBox.Show("Success!"); // (X) 메세지를 출력한다.
// (O) 메세지를 출력한다.
MessageBox.Show("Success!");
2-2. 주석 텍스트는 대문자로 시작합니다.
// I don't know what now I'm talking about.
// 한글 주석은 해당사항이 없습니다.
2-3. 주석 텍스트 끝에는 마침표를 붙입니다.
// 주석 텍스트 문장의 끝에는
// 마침표를 붙입니다.
2-4. 주석 구분 기호(//)와 주석 텍스트 사이에 공백을 하나 삽입합니다.
//이렇게 붙여서 사용하지 마시고
// 한칸 띄워서 주석을 작성하시면 됩니다.
2-5. 서식이 지정된 별표 블록으로 주석을 묶지 않습니다.
//***************************
//* 이런식으로 주석을 작성하지 말라는 뜻입니다. *
//* 예전C, C++에서 이런 스타일의 주석을 작성하였습니다. *
//* 관련 링크 : https://www.reddit.com/r/csharp/comments/am098s/formatted_blocks_of_asterisks_around_comments_in/ *
//***************************
3. 문법 관련 규칙
3-1. 짧은 문자열을 연결할 때에는 문자열 보간을 사용합니다.
string lastName = "Lee";
string firstName = "HyoSeong";
// $가 앞에 붙는 것이 특징입니다.
// 문자열 보간에 대한 자세한 내용은
// https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/tokens/interpolated
// 를 참고하세요.
// 이 기능은 C# 6.0에 추가되었습니다.
string displayName = $"{lastName}, {firstName}";
3-2. 많은 양의 텍스트를 사용할 때 문자열을 루프에 추가하려면 StringBuilder 개체를 사용합니다.
var phrase = "lalalalalalalalalalalalalalalalalalalalalalalalalalalalalala";
var manyPhrases = new StringBuilder();
for (var i = 0; i < 10000; i++)
{
manyPhrases.Append(phrase);
}
3-3. 할당 오른쪽에서 변수 형식이 명확하면 암시적 형식을 사용합니다.
var var1 = "이건 누가봐도 문자열입니다.";
var var2 = 27;
3-4. 정확한 형식이 중요하지 않으면 지역 변수에 대해 암시적 형식을 사용합니다.
3-5. 할당 오른쪽에서 변수 형식이 명확하지 않으면 암시적 형식을 사용하지 않습니다.
// 아래 코드들은 보기에는 명확해 보이지만 명확하지 않은 할당입니다.
// 명확한 할당이란 new 연산자나 명시적 캐스트인 경우 명확한 것으로 간주됩니다.
int var3 = Convert.ToInt32(Console.ReadLine());
int var4 = ExampleClass.ResultSoFar();
3-6. 변수 이름을 사용하여 변수 형식을 지정하지 않습니다.
// 형식이 올바르게 지정되지 않을 수 있습니다.
// 아래의 inputInt는 실제로는 string입니다.
var inputInt = Console.ReadLine();
Console.WriteLine(inputInt);
3-7. dynamic 대신 var를 사용하지 않습니다.
// dynamic은 런타임 형식 유추입니다.
// 비슷해 보이지만 성질이 전혀 다른 문법입니다.
// var은 컴파일러에서 변수의 형식을 유추합니다.
// dynamic은 object처럼 동작하고 모든 연산을 지원하는 것으로 간주됩니다.
// 런타임 에러가 발생할 소지가 있습니다.
3-8. for 루프의 루프 변수 형식을 결정하려면 암시적 형식을 사용합니다.
var phrase = "lalalalalalalalalalalalalalalalalalalalalalalalalalalalalala";
var manyPhrases = new StringBuilder();
// 오른쪽 할당이 명시적입니다.
for (var i = 0; i < 10000; i++)
{
manyPhrases.Append(phrase);
}
3-9. foreach 루프의 경우 암시적 형식을 사용하지 않습니다.
// 오른쪽 할당이 명시적입니다.
var laugh = "acdhhhdd";
// laugh에 대한 foreach요소가 명시적이지 않습니다.
// 따라서 var을 사용하지 않습니다.
foreach (char ch in laugh)
{
if (ch == 'h')
Console.Write("H");
else
Console.Write(ch);
}
3-10. 일반적으로 uint(부호 없는 형식) 대신 int를 사용합니다.
// uint 형식은 일반적으로 잘 사용하지 않아
// 다른 라이브러리와의 상호작용이 힘들 수 있습니다.
uint count = 4;
// 보편적인 int 사용을 권장합니다.
int count2 = 4;
3-11. 배열을 간결한 구문을 사용하여 선언할 때에는 var을 사용할 수 없습니다.
string[] vowels1 = { "a", "e", "i", "o", "u" };
3-12. 하지만 명시적 인스턴스화를 사용하는 경우 var을 사용할 수 있습니다.
var vowels2 = new string[] { "a", "e", "i", "o", "u" };
3-13. 배열 크기를 지정하는 경우 한 번에 하나씩 요소를 초기화해야 합니다.
var vowels3 = new string[5];
vowels3[0] = "a";
vowels3[1] = "e";
3-14. Delegate 형식을 정의하는 대신 Func<>, Action<>을 사용합니다.
// Func<> Atcion<> 예제
class ActionClass
{
public Action<int> Action1 = x => Console.WriteLine($"x is: {x}");
public ActionClass()
{
Action1(3);
}
}
// delegate 예제
class DelegateClass
{
public delegate void Delegate1(int x);
public void RunThis(int x)
{
Console.WriteLine($"x is: {x}");
}
public DelegateClass()
{
Delegate1 run = new Delegate1(RunThis);
run(3);
}
}
3-15. try-finally Dispose 말고 using을 사용합니다.
// 아래 1번과 2번은 동일한 코드입니다.
// 1. try- finally Dispose 패턴
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
{
((IDisposable)font1).Dispose();
}
}
// 2. using 패턴
using (Font font2 = new Font("Arial", 10.0f))
{
byte charset2 = font2.GdiCharSet;
}
3-16. &대신 &&, | 대신 ||를 사용합니다.
// 아래의 경우 & 연산은 둘 다 계산하고, &&연산은 한번만 계산합니다.
if ((divisor != 0) && (dividend / divisor > 0))
{
Console.WriteLine("Quotient: {0}", dividend / divisor);
}
if ((divisor != 0) & (dividend / divisor > 0))
{
Console.WriteLine("Quotient: {0}", dividend / divisor);
}
3-17. 간결한 new 사용
// 아래 코드는 동일한 코드입니다.
var instance1 = new ExampleClass();
ExampleClass instance2 = new();
ExampleClass instance3 = new ExampleClass();
// 또한 아래 코드도 동일한 코드입니다.
// 개체 이니셜라이저를 사용하면 코드 간소화가 가능합니다.
var instance5 = new ExampleClass { Name = "Desktop", ID = 37414,
Location = "Redmond", Age = 2.3 };
var instance6 = new ExampleClass();
instance6.Name = "Desktop";
instance6.ID = 37414;
instance6.Location = "Redmond";
instance6.Age = 2.3;
3-18. 제거가 필요없는 이벤트 정의 시, 람다 식을 사용합니다.
// 1. 람다식을 사용하여 이벤트 정의
public Form2()
{
this.Click += (s, e) =>
{
MessageBox.Show(
((MouseEventArgs)e).Location.ToString());
};
}
// 2. 별도의 함수로 분리하여 이벤트 정의
public Form1()
{
this.Click += new EventHandler(Form1_Click);
}
void Form1_Click(object sender, EventArgs e)
{
MessageBox.Show(((MouseEventArgs)e).Location.ToString());
}
감사합니다.
반응형
'C#' 카테고리의 다른 글
[C#] .net 4.0 기본 연결이 닫혔습니다. (tls 1.2) (https) (2) | 2021.05.07 |
---|---|
[C#] Visual Studio 빌드시 pdb 파일 안나오게 하는법(or 나오게 하는법) (0) | 2021.05.07 |
[C#] parse string to enum 대소문자 무시 (ignore case) (0) | 2021.03.02 |
[C#] enum to string, string to enum 변환 (0) | 2021.03.01 |
[C#] 다른 프로세스가 읽을 수 있게 파일 열기 (FileAccess, FileShare) (0) | 2021.02.26 |