C# 기본개념 질문

안녕하세요. 원래 자바 스프링 신입으로 입사했다가, 몇개월정도 지난 지금 어찌저찌 회사의 사정상 C#으로 프로젝트 구성이 바뀐다(확정) 라는 이야기를 듣고 C#을 공부중입니다. 다행히도 자바와 비슷한 구조를 가지고 있어서 나아가고 있으며, 회사에서도 충분한? 학습기간을 제공해주기로 했습니다. 하지만, 몇몇 주제들은 저에게 ? 를 띄우기도 합니다. 전체를 다 질문하는 건 무리일 것 같고, 정식 도큐멘트에 안나올 법한 질문만 몇개 드리겠습니다.

  1. C# 공통 질문
    a. 왜, 변수명은 카멜케이스인데, 메서드들은 카멜케이스가 적용되어있지 않은것들이 대부분인가요? (대부분이라 표현한 이유는, 제가 모든 함수를 사용해본게 아니라서 여태 본 함수들은 이러한 패턴들을 가지고 있어서) ex) args.Length / Console.WriteLine
    예상안 → args.length / Console.writeLine

b. 자바에서 쓰던 습관이 있어서 shortcut을설정하다가, Console.Write 와 Console.out.write 를발견했습니다. 두개다 실행결과 똑 같은 결과가 나왔습니다. 설명상에는 콘솔과 파일의 출력이라고는 되어있지만, 정확한 차이를 모르겠습니다.

c. NET6 템플릿 변경사항이 생긴 것 같은데, 클래스를 사용하지 않는 템플릿인 것 같습니다. 배웠던바로는 클래스는 객체지향프로그래밍의 기본개념으로 알고 있습니다. 또한 C#도 기본툴은 OOP설계 중요하다고 알고있습니다. 하지만, .NET에서 이러한 기능을 추가 지원한다는 건, 단일 프로젝트 설계를 위한 간단한 코드를 위해서 인가요?

  1. 데이터 형식(정수계열)
    a. 앞에 u가 붙은 친구들을 자주 사용하나요? 또한 byte는 왜 signed 를 구분 시켜놓은건가요?

a-1 자주 사용하지 않는 다면, 어째서 인가요. 같은 메모리범위를 사용하지만 양수만을 사용한다면 두배의 범위를 지원하는 것인데.

b. 3_0000_0000 이렇게 4자리 형식으로 끊어도 되지만 몇의 자리로 끊는 것은 사용자의 마음이라고 했습니다. 하지만 혹시 약속 같은게 있나요. 몇의자리에서 끊자라는?

c. int a = int.MaxValue 와 var a = int.MaxValue 로 선언해도 같은 값이라는 것을 확인했고, var의 패키지 내부파일을 보려고 들어갔더니, int 로 연결되는 것을 보니, 뭐라고 선언해주는지에 따라 바뀌는 것 같은데, 모든 변수의 선언 을 var라고 하면 편할 것 같은데, 메모리상의 더 잡아먹는 구조라던지, 아니면 타입의 모호함으로 인해 이상해지는 케이스가 생길 수 있나요?

  1. 추가사항.
    c# documentation 은 ms에서 제공하는
    C# 문서 - 시작, 자습서, 참조. | Microsoft Learn
    이친구가 맞나요? 한글을 지원하니 어색해서요. 서브문서인가 싶어서 여쭙습니다.

감사합니다. 수준 낮은 질문이라는 것은 이해하지만, 아직 시니어 개발자분을 만나기전에는 기초정도는 확립하고 싶어서 질문드립니다. 좋은하루되세여!

3 Likes
  1. 메서드명이 카멜케이스가 아닌 이유
    심플합니다. MS가 그렇게 쓰기 때문입니다. MS의 권고사양이지요.
    때문에 Property와 Method는 파스칼케이스가 일반적입니다.
    메서드 내부의 지역변수가 카멜케이스로 많이 쓰입니다.
    하지만 강제는 아니기에, 카멜케이스로 Method와 Property를 사용하시는 분도 계십니다.
    다만 이 경우 Visual Studio에서 주의 사항으로 내뱉습니다. (물론 끌 수 있음)

  2. Console.Write vs Console.out.write
    Console.out.write은 써본적도 없고 처음 봅니다.
    찾아보면 있을 수 있겠으나 따로 찾아보고 답변드리는 것은 아닙니다.
    다만, C#을 9년째 다루고 있는 저로서는 Console.out.write은 사용해본적이 없습니다.
    나중에 찾게되면 추후 댓글로 남기겠습니다.
    그냥 Console.Write 쓰시면 될 것 같습니다.

  3. 아무래도 .NET 5에서 추가된 Console 프로젝트의 Top-Level Programming을 접하신 것 같습니다.
    이것은 사실 Main함수가 있는데 그냥 안 나오는 것입니다.
    Main함수를 적어줘도 됩니다.
    짧은 스크립트로 직관적으로 Console Application을 통해 Test 해볼 수 있습니다.
    물론 비지니스를 구현해도 됩니다.
    개발자 마음이죠.
    그리고 C#은 객체지향을 완벽하게 지원할 뿐입니다.
    객체지향만 해야하는 것은 아닙니다.

  4. signed 사용 유무
    저도 사용하던 때가 있었습니다.
    다만 숫자 자료형의 최대값을 사용하는 업무는 도메인마다 다릅니다.
    따라서 자료형을 확실하게 지킬 필요는 없다고 생각합니다.
    게다가 json같은 문자열로 통신할 경우 문자열에는 type이 붙어있지 않습니다.
    따라서 변환하는 자료형에 그냥 overflow만 일어나지 않으면 됩니다.
    그리고 메모리를 크게 신경쓰지 않고 로직에 집중하기도 합니다. (물론 개발자마다 다름)
    자료형을 꼼꼼하게 챙기는 개발자는 도메인과 팀원 지식수준에 따라 팀원을 피곤하게 할 수도 있습니다.
    그리고 결정적으로 저는 SQL Server 데이터 베이스를 주로 사용했는데, SQL Server에는 unsigned 타입을 지원하지 않습니다.
    ORM을 즐겨사용하는 저로서는 그래서 안 쓰게 되었습니다.

  5. 3_0000_0000 이건 그냥 취향같아요.

  6. var
    var는 타입 추론형 정적인 타입입니다.
    int던 double이던 아니면 사용자가 정의한 class 자료형이던지 var로 받을 수 있습니다.
    var를 쓰는 이유는 여러가지가 있습니다.
    가장 첫번째로는 휴먼에러를 잡기 위함입니다.
    자료형에 관해서는 사람보다는 직접 프로그램을 빌드하고 돌리는 IDE가 더 똑똑합니다.
    숫자가 5가 있다면, 이것을 long이던 int던 short던 byte로든 다 받을 수 있습니다.
    이것을 각자 타입으로 선언하는게 아니라 var로 하면 알아서 맞는 타입으로 넣어줍니다.
    var는 정의된 타입이 아닙니다.
    코딩할 때도 var에 마우스를 대보면 (int) 또는 (double) 이런 식으로 써있습니다.
    일종의 Alias 개념이라고 보시면 될 거 같아요.
    메모리를 더 잡아먹는 그런 것은 정확히는 모르겠습니다.
    어차피 그냥 alias니까 런타임에서는 추론하여 확정된 타입으로 돌아갈 것이기 때문에 메모리를 더 잡아 먹지는 않을 것 같아요.

  7. MSDN을 사랑하시고 Microsoft Learn 도 사랑하세요. 한글본과 영어버전 모두 보시는 것이 좋습니다.
    그리고 이해가 안되게 써놓은 문장도 이해를 하시는 게 좋습니다. MSDN은 상당히 강력합니다.

5 Likes

감사합니다. 기초적인 질문임에도 불구하고 많은 도움이 된것같습니다. 친절한 설명도 감사합니다! 즐거운 금요일 되세요!

1 Like

Console.Out 속성은 TextWriter 를 반환합니다.
반환 받은 TextWriter의 속성을 변경할 수 있습니다.
예를 들어, 윈도우에서는 Console.WriteLine() 함수는 "\n\r"을 추가하는데요.
TextWrtiter의 속성 NewLine을 "\n"으로 변경할 수 있습니다.
Console.Out 속성은 지정된 TextWrite의 속성을 변경할 때 사용되면
Console.Write와 Console.Out.Write 는 동일한 동작을 합니다.

질문 중 콘솔과 파일의 출력이라고 된 부분은
Console.Setout() 함수를 사용하여 출력을 변경한 부분입니다.

MSDN 발췌한 코드로
Console.Setout(sw) 부분이 파일로 출력을 변경한 부분입니다.

using System;
using System.IO;

public class Example
{
   public static void Main()
   {
      // Get all files in the current directory.
      string[] files = Directory.GetFiles(".");
      Array.Sort(files);

      // Display the files to the current output source to the console.
      Console.Out.WriteLine("First display of filenames to the console:");
      Array.ForEach(files, s => Console.Out.WriteLine(s));
      Console.Out.WriteLine();

      // Redirect output to a file named Files.txt and write file list.
      StreamWriter sw = new StreamWriter(@".\Files.txt");
      sw.AutoFlush = true;
      Console.SetOut(sw);
      Console.Out.WriteLine("Display filenames to a file:");
      Array.ForEach(files, s => Console.Out.WriteLine(s));
      Console.Out.WriteLine();

      // Close previous output stream and redirect output to standard output.
      Console.Out.Close();
      sw = new StreamWriter(Console.OpenStandardOutput());
      sw.AutoFlush = true;
      Console.SetOut(sw);

      // Display the files to the current output source to the console.
      Console.Out.WriteLine("Second display of filenames to the console:");
      Array.ForEach(files, s => Console.Out.WriteLine(s));
   }
}

저는 예전에 Console.SetOut() 함수를 사용하여 윈폼상의 리스트 박스로 출력을
한 적이 있어서 답변 달아봅니다.

3 Likes

답변 주신 내용 첨부로 MS에서 권고하는 대/소문자 표기법 전달 드립니다.

제가 이 문서에서 얻은 내용으론 IDIdid로 사용하라고 권고한 내용입니다.
ID로 사용했었거든요 ㅋㅋㅋ 간단한 문서니 한번 훑어봐도 좋을 것 같습니다!

4 Likes

두분모두 답글 감사합니다. 차근차근 계속 읽어봐여겠습니다!
주 시작도 모두 화이팅입니다!

1 Like

다른 분들의 답변에 덧붙이자면,

  1. Console.Write… 은 Console.Out.Write 의 축약형으로 완전히 동일하게 동작합니다.
    전자의 정의를 살펴 보면 내부에서 후자를 호출하는 거 외에는 아무 것도 없습니다.
    동일하기 때문에, 몇 글자라도 더 적은 전자를 사용하는 것이 일반적입니다.

  2. unsigned 자료형은 시스템, 프레임워크 간 호환성 문제가 있을 수 있습니다.
    이는 닷넷(C#) 만의 문제는 아니며 모든 개발 도구의 공통 사항입니다. 예를 들어, 어떤 데이터베이스는 unsigned 형식의 숫자를 지원하지 않습니다.
    이러한 호환성 문제 때문에, 닷넷은 가급적 signed 자료형(uint 대신에, int 를)을 일반적으로 사용하기를 권고합니다. 그리고 정수는 int, 부동은 double 이, 금융/회계 관련해서는 decimal (은 일반적인 용도로 사용하면 성능 저하가 큽니다)이 거의 표준입니다.

  3. var 는 컴파일 타임에 "유추"되는 형식입니다.
    예를 들어, int i = 10; 으로 선언 했는데, 나중에 해상도가 모자라서 long 으로 변경한 경우, int 를 long으로 일일이 찾아서 변경해야 합니다. 이 경우, 애초에 var i = 10; 으로 정의했다면 컴파일러가 알아서 유추하기 때문에, 프로그래머의 수고를 덜 수 있습니다. 닷넷도 가급적 var를 사용하라고 권고하고 있고, 많은 개발자가 그렇게 하고 있습니다.
    뿐만 아니라, 컴파일러는 유추된 형식으로 소스코드를 확정하기 때문에, 런타임에 성능 차이가 없습니다.
    var 에 대비되는 dynamic 이 있는데, 이는 런타임에 "결정"되는 형식입니다.
    dynamic 은 컴파일 타임에 알 수가 없기에 컴파일러가 하는 일은 없습니다.

4 Likes