language/c#

[C#] 01. C#과 닷넷 생태계, 첫 프로그램

렁치 2026. 7. 8. 23:11

C#은 C, C++ 같은 컴파일 언어의 성능과 자바스크립트, 파이썬, PHP 같은 인터프리터 언어의 편의를 함께 노린 언어다. 자바와 비슷한 위치에 있는 하이브리드 언어라고 보면 된다.

그런데 C#을 제대로 이해하려면 언어 문법 이전에 그 언어가 올라타 있는 닷넷(.NET)이라는 플랫폼을 먼저 봐야 한다. 이 글에서는 C#이 어떤 언어인지, 닷넷 생태계가 어떻게 구성되는지, 그리고 첫 프로그램을 어떻게 쓰는지를 정리한다.


1. C#이라는 언어

C#은 마이크로소프트가 만든 객체 지향 프로그래밍 언어이자, 마이크로소프트의 닷넷 플랫폼을 기반으로 도는 여러 언어 중 하나다. 특징을 먼저 훑어보면 이렇다.

  • 절차적 스타일, 객체 지향 스타일, 함수형 스타일을 모두 지원하는 다중 패러다임 언어
  • 전역 함수나 전역 변수가 없고, 모든 코드가 클래스 안에서 정의됨
  • 메모리를 자동으로 관리(GC, Garbage Collection)
  • 제네릭(generic)과 LINQ(Language Integrated Query) 같은 기능을 언어 차원에서 제공
100% 하위 호환성
C#의 독특한 점 중 하나는 하위 호환을 강하게 지킨다는 것이다. 1.0 버전부터 최신 버전까지, 낮은 버전에서 지원하던 기능이 버전이 올라가면서 사라진 경우가 없다. 예전에 쓰던 문법이 새 버전에서도 그대로 동작하므로, 오래된 코드를 최신 컴파일러로 돌려도 깨지지 않는다.

 

초창기 C#은 윈도우 기반의 닷넷 프레임워크(.NET Framework)에서만 실행됐다. 최근에는 크로스 플랫폼을 지원하는 닷넷 코어(.NET Core) 기반으로 제공된다. 이 둘을 합쳐서 그냥 "닷넷"이라고 부른다.


2. 닷넷(.NET) 생태계

닷넷(.NET)
응용 프로그램 개발 속도를 높여주는 소프트웨어 프레임워크다. 실행에 필요한 API(Application Programming Interface)와 서비스를 모아둔 것으로, 다음을 포함한다.
  • 런타임 엔진(코드를 실제로 돌리는 명령어 집합)
  • 여러 언어 지원: C#, Visual Basic, F#
  • 웹, 데스크톱, 모바일, 게임, IoT, 클라우드 등 다양한 개발 환경

 

C#은 이 닷넷 위에서 도는 언어이므로, 닷넷을 구성하는 요소들을 알아두면 전체 그림이 잡힌다.

 

구성 요소 설명
닷넷 프레임워크(.NET Framework) 윈도우 기반 OS에 설치되는 실행 환경. ASP.NET, Windows Forms, WPF 등을 포함한다. C#은 이 프레임워크의 일부로 동작한다.
닷넷 코어(.NET Core) 크로스 플랫폼을 지원하는 실행 환경. ASP.NET Core, Blazor, Windows Forms, WPF 등을 포함하며, 성능 향상에 중점을 둔다. 서로 다른 버전을 한 머신에서 함께 실행할 수 있다.
자마린(Xamarin) C#과 XAML로 iOS, Android용 모바일 응용 프로그램을 만드는 기술.
닷넷 스탠다드(.NET Standard) 프레임워크·코어·자마린에서 공통으로 쓸 코드를 하나의 프로젝트로 모아 관리하는 규격.
유니티(Unity) 닷넷 생태계에 직접 포함되지는 않지만, C#을 주요 스크립팅 언어로 쓰는 유명한 게임 엔진.

 

닷넷 내부는 크게 둘로 나뉜다.

  • CLR(Common Language Runtime): 런타임 엔진으로, 닷넷의 모든 소프트웨어를 실제로 돌리는 엔진 역할을 한다.
  • FCL(Framework Class Library): 닷넷 개발에 필요한 필수 라이브러리 클래스의 집합이다.

 

C# 소스는 곧바로 기계어가 되는 것이 아니라 중간 언어로 컴파일되고, 그 중간 언어를 CLR이 받아 실행한다. 자바에서 소스를 바이트코드로 컴파일하고 JVM이 실행하던 구조와 비슷하다. 이 CLR이 있기 때문에 여러 닷넷 언어(C#, F#, Visual Basic)가 하나의 런타임 위에서 함께 어울릴 수 있다.


3. 프로젝트와 솔루션

C#으로 개발할 때는 파일 하나만 다루는 게 아니라 프로젝트와 솔루션이라는 단위로 코드를 묶는다. 비주얼 스튜디오를 처음 켜면 마주치는 개념이라 짚어둔다.

 

프로젝트(project)와 솔루션(solution)
  • 프로젝트: 프로그램 하나를 이루는 가장 작은 단위. 관련된 여러 파일을 이름 하나로 묶는다. 확장자는 CSPROJ(C# 프로젝트).
  • 솔루션: 하나 이상의 프로젝트를 모아 관리하는 상위 단위. 확장자는 SLN.

 

정리하면 "파일이 모여 프로젝트, 프로젝트가 모여 솔루션"이다. 작은 실습에서는 프로젝트 하나에 솔루션 하나가 붙는 구조로 시작하지만, 규모가 커지면 하나의 솔루션 안에 여러 프로젝트(예: 실행 프로그램, 공용 라이브러리, 테스트)를 함께 두게 된다.


4. 첫 프로그램: Hello, World

using System;

namespace HelloWorld
{
    class HelloWorld
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

 

이 짧은 코드에 C# 프로그램의 기본 골격이 다 들어 있다. 바깥에서부터 안으로 네임스페이스 > 클래스 > Main() 메서드 순으로 감싸는 구조다.

 

콘솔 화면에 문자열을 출력하는 원래 형태는 "네임스페이스.클래스.메서드();"다. 즉 System.Console.WriteLine("...")처럼 써야 한다.

 

여기서 using 키워드가 등장한다. 파일 맨 위에 using System;을 적어두면 System 네임스페이스를 생략하고 Console.WriteLine("...")처럼 줄여 쓸 수 있다.

 

이름을 줄여 쓰는 단계
  • System.Console.WriteLine(); (전체를 다 씀)
  • using System; → Console.WriteLine(); (네임스페이스 생략)
  • using static System.Console; → WriteLine(); (클래스까지 생략, C# 6.0 이상)

 

System.Console.WriteLine처럼 네임스페이스와 형식 이름까지 전부 적어 어디에도 헷갈리지 않게 지정하는 방식을 정규화된 이름(fully qualified names)이라고 한다.

 

Main() 메서드는 프로그램의 시작점이다. 앞에 붙은 static 덕분에 객체를 따로 생성하지 않고도 클래스에 있는 Main()을 바로 호출할 수 있다. 프로그램의 진입점은 객체가 만들어지기 전에 실행돼야 하므로 static이 필요한 것이다.

비주얼 스튜디오에는 이 뼈대를 자동으로 채워주는 스니펫이 있다.

 

  • svm 입력 후 Tab을 두 번 → static void Main() {} 블록 생성
  • cw 입력 후 Tab을 두 번 → Console.WriteLine(); 자동 입력

 

참고로 C#은 여는 중괄호를 다음 줄에 두는 Allman 스타일을 주로 쓴다. 위 예제처럼 {가 선언과 같은 줄이 아니라 아래 줄에 내려와 있는 형태다.


5. 최상위문(top-level statements)

앞의 Hello, World 코드를 보면, 정작 하고 싶은 일은 Console.WriteLine("Hello, World!"); 한 줄인데 네임스페이스와 클래스, Main()이 겹겹이 감싸고 있다. C# 9.0부터는 이 껍데기를 걷어낼 수 있다.

 

최상위문(top-level statements)
C# 9.0에서 도입된 기능으로, Main() 메서드를 직접 쓰지 않고도 프로그램의 진입점을 정의할 수 있다. 불필요한 코드를 줄여주어 간단한 스크립트, 코드 예제, 학습용 프로그램에 유용하다.

 

Console.WriteLine("Hello, World!");

 

이 한 줄이 그대로 완전한 프로그램이 된다. 진입점과 실행 코드가 모두 이 한 줄에 정의된 셈이다.

사라진 것처럼 보이는 Main()은 실제로는 컴파일러가 뒤에서 자동으로 만들어준다. 개발자가 껍데기를 안 쓰는 것일 뿐, 프로그램이 시작점 없이 도는 것은 아니다.


한 걸음 더

  • C#과 자바는 구조가 상당히 닮았다. 소스를 중간 언어로 컴파일하고 런타임(C#은 CLR, 자바는 JVM)이 실행하는 방식, GC로 메모리를 자동 관리하는 점, 모든 코드가 클래스 안에 들어가는 점이 그렇다. 실제로 C#은 자바를 강하게 의식하며 설계됐다. 다만 C#은 프로퍼티, LINQ, 델리게이트처럼 자바에 없던 문법을 일찍부터 넣어 나름의 색을 냈다.
  • 최상위문은 편하지만, 큰 프로그램에서 늘 쓰기 좋은 것은 아니다. 학습용·스크립트용 짧은 코드에서는 껍데기를 걷어낸 게 깔끔하지만, 여러 클래스와 파일로 구조를 나눠야 하는 규모에서는 오히려 명시적인 Main()과 네임스페이스가 코드의 시작점과 구성을 분명히 보여준다. 그래서 실무 프로젝트 템플릿은 상황에 따라 두 방식을 모두 쓴다.
  • 닷넷 프레임워크와 닷넷 코어가 갈라졌다가 다시 "닷넷"으로 합쳐진 흐름도 눈여겨볼 만하다. 처음엔 윈도우 전용이던 프레임워크를 리눅스·맥에서도 돌리려고 크로스 플랫폼 코어를 새로 만들었고, 이제는 코어 계열이 사실상 표준이 되어 그냥 닷넷으로 불린다. "윈도우 위의 C#"에서 "어디서든 도는 C#"으로 넓어진 과정인 셈이다.