닷넷은 2002년에 마이크로소프트에서 발표한 닷 넷 프레임워크(.NET Framework)에서 발전한 응용 프로그램 개발 환경
→ 프로세스 가상머신
일반적인 네이티브 언어로 만들어진 프로그램들이 운영체제에서 곧바로 실행되는 것과는 달리 닷넷을 기반으로 만들어진 응용 프로그램은 그에 더해 런타임 환경을 필요로 한다.
3가지 방식을 통해 배포가 가능
- 닷넷 런타임을 시스템에 설치
- 닷넷 런타임을 응용프로그램과 함께 배포
- 실행 파일 내에 닷넷 런타임을 포함
.NET Runtime이전에 CoreCLR이라고 불렸으며, 관련 모듈(coreclr.dll)의 이름에서 흔적을 찾아볼 수 있다. - 오픈소스
첫 번째 방식의 경우 시스템에 전역적으로 설치되므로 응용 프로그램을 빌드한 파일만 복사하면 실행이 가능하다.
두 번째 방식은 응용 프로그램마다 런타임 파일들을 함께 배포하므로 디스크 공간이 낭비된다는 단점이 있으나, 대상 컴퓨터에 닷넷 런타임 설치 여부를 신경 쓸 필요가 없다는 편리함이 있다.
세 번째 방식은 단일 실행 파일에 런타임 구성 요소까지 모두 포함해 배포의 편의성을 극단적으로 높였다.
3가지 방식에 상관없이 .NET Runtime은 언제나 필요하다.
C# 컴파일러는 소스코드를 기계어가 아닌 IL(Intermediate Language)이라고 하는 중간 언어로 실행파일(ex: EXE/DLL) 내부에 생성한다.
프로그램이 시작하자마자 .NET Runtime을 로드하는 코드를 자동으로 실행 파일 내부에 추가.
사용자가 C#으로 개발된 애플리케이션을 실행하면 내부적으로 .NET Runtime이 먼저 로드된다.
.NET Runtime은 실행 파일 내에 있는 중간언어 코드를 로드해서 본격적인 실행 단계에 들어선다.
.NET 호환 언어
.NET Runtime에 의해 실행되는 중간 언어는 어느 하나의 프로그래밍 언어에 종속된 것이 아니다.
어떤 언어의 컴파일러든지 결과물을 중간 언어로 생성해 낸다면 런타임이 그것을 실행할 수 있다.
중간 언어로 번역하는 언어를 닷넷 호환 언어(.NET Compliant Language)라고 한다. C#은 그러한 언어 중 하나이다.
닷넷 호환 언어는 IL(중간 언어) 코드의 결과물을 공유하기 때문에 상호 호출이 가능
ex) C#에서 만든 클래스를 F#에서 사용가능하며, 다른 언어로 만든 클래스까지도 상속받을 수 있다.
마이크로소프트에 의해 공식적으로 제공되는 닷넷 호환 언어 : C#, Cisual Basic, .NET, F#, C++/CLI가 있다.
기존의 COBOL, Lisp, Python, PHP, RUBY 등의 언어도 닷넷 환경에서 실행할 수 있게 중간 언어를 산출하는 버전들이 발표되었다. 원할 경우 내려받아 사용 가능 - 현실적으로 사용할 만한 닷넷 호환 언어는 파이썬을 위한 IronPython이 유일하다.
공통 중간 언어(CIL : Common Intermediate Language)
자바의 VM에서는 중간 언어를 바이트코드(Bytecode)라고 한다.
.NET Runtime에서는 이를 CIL(Common Intermediate Language)이라고 하며, IL 코드, 또는 MSIL 코드라고 한다.
CPU에 독립적인 결과물로서 모든 닷넷 호환 언어는 소스코드를 IL코드로 컴파일하고, 런타임이 실행될 때 IL 코드를 CPU의 기계어로 최종 번역한다.
IL코드는 그 자체로 프로그래밍 언어 문법을 가지며 ILASM.EXE라는 컴파일러를 가지고 있다.
class Program
{
static void Main(string[] args)
{
int a = 5;
int b = 6;
int c = a + b;
}
}
해당 예제를 C# 컴파일러로 빌드하면 중간 언어인 IL 코드로 변환된다.
IL 코드는 가상 머신에서 실행된다는 의미에서 기계어와 유사함
기계어와 일대일 대응되는 어셈블리 언어가 있는 것처럼 IL 코드도 일대일 대응되는 IL 언어가 따로 있다.
IL 소스코드를 ilasm 프로그램을 이용해 컴파일하면 C#에서와 동일한 프로그램이 생성된다.
이러한 특징 덕분에 닷넷 호환 언어는 두 가지 방법으로 구현되고 있다.
ex) COBOL 언어를 닷넷용으로 만든다고 가정
- C# 언어처럼 COLBOL 소스코드에서 곧바로 중간 언어를 생성할 수 있도록 만들 수 있다.
- COLBOL 소스코드를 일단 IL 소스코드로 변환한 후 컴파일 할 수 있는 ilasm.exe의 도움을 받아 실행 파일을 만드는 유형
공용 타입 시스템
닷넷 호환 언어가 지켜야 할 타입(Type)의 표준 규격을 정의한 것이 공용 타입 시스템(CTS: Common Type System)이다.
새로운 언어를 만들어 닷넷 런타임에서 실행하고 싶다면 CTS 규약을 만족하는 한도 내에서만 구현할 수 있다.
ex) CTS에서는 클래스 상속을 하나만 받을 수있도록 정의하고 있고, 이로 인해 직접 닷넷 호환 언어를 만들 때 클래스의 다중 상속을 지원하도록 만들 수 없다.
실제로 중간 언어에서는 다중 상속과 관련된 어떤 IL코드 표현도 제공하지 않는다.
닷넷 호환 언어는 CTS의 한계를 넘어서 구현할 수 없다.
다른 특징으로는 닷넷 호환 언어가 CTS에서 정의한 모든 규격을 구현할 필요도 없다.
ex) CTS에서는 타입의 접근성에 대해 public, private, ... 등으로 나누고 있지만, 닷넷 호환 언어에서는 public 만 지원하도록 만드는 것이 가능하다.
언어에서 필요하지 않다면 굳이 CTS에서 정의한 접근성에 모두 대응하지 않아도 된다.
C#과 Visual Basic .NET 언어는 CTS가 정의한 타입 시스템의 일부를 자신들의 언어 사양에 맞게 구현하고 있다.
CTS 전체를 활용해 프로그램을 만들고 싶다면 IL 언어를 사용하거나 CTS 전체 규격을 표현한 언어를 새롭게 만들어야 한다.
공용 언어 사양
닷넷 호환 언어가 지켜야 할 최소한의 언어 사영을 정의한 것이 공용 언어 사양(CLS: Common Language Specification)이다.
직접 닷넷 호환 언어를 만들고 싶다면 CTS 전체를 구현할 필요는 없어도 CLS에 명시된 사양만큼은 완벽하게 구현해야 한다.
ex) C#에서는 부호 없는(Unsigned) 형식을 지원한다. 이는 CTS에 정의되었기에 C#에서도 정의할 수 있다.
CLS에서는 Unsigned 타입을 강제화하지 않았다. 따라서 C#에서 unsigned 타입이 구현됐다고 해서 다른 언어에서도 unsigned 타입이 구현됐다고 보장 X
- 왜 이것이 문제되는가?
닷넷 호환 언어기리는 서로 사용할 수 있고 상속도 받을 수 있다는 사실을 보면, C# 언어에서 unsigned 타입을 사용하는 메서드를 정의했다고 가정했을 때, unsigned를 지원하지 않는 다른 언어에서는 이 메서드를 사용할 때 호환성 문제가 발생
→ 서로 다른 언어를 섞어서 프로그램을 만들어야 한다면 외부에서 사용할 기능에 대해서는 CLS를 준수해야 한다.
CLS는 두 가지 측면에서 의미가 있다.
- 모든 닷넷 호환 언어가 CLS에서 정의한 사양만큼은 구현해야 한다.
- 닷넷 호환 언어끼리 호출해야 하는 경우에는 그 기능에 한해서 CLS를 만족시키도록 작성해야 한다.
CLS, CTS와 닷넷 호환 언어의 관계 정리
메타데이터
일반적인 정의로는 데이터를 위한 데이터를 메타데이터(Matadata)라고 한다.
ex) 그림 파일에서는 그림을 나타내는 컬러 값이 그림을 이루는 '데이터'가 된다.
프로그래밍에서 메타데이터의 정확한 의미를 이해하려면 기존 네이티브 언어의 특징을 먼저 이해해야 한다.
ex) Visual C++로 다음과 같이 2개의 클래스로 정의한 경우
이 소스코드를 컴파일해서 생성한 실행 파일로부터 개발자가 만든 클래스의 어떠한 정보도 알아낼 수 없다.
Visual C++ 컴파일러는 위와 같은 클래스 정보를 설명하는 메타데이터를 생성하지 않기 때문이다.
→ 프로그래밍 언어에서는 개발자가 구현한 코드가 데이터에 해당하고, 해당 코드의 성격을 설명해주는 별도의 데이터를 메타데이터라고 한다.
.NET Runtime에서 동작하는 실행 파일은 완전하게 자기 서술적인(self-descriptive) 메타데이터를 제공하며, 외부에서는 이런 정보를 리플렉션(Reflection)이라는 기술을 통해 사용할 수 있다.
직접 닷넷 호환 언어를 만들어 컴파일러를 제공한다면 중간 언어 코드는 물론이고 그에 대한 메타데이터도 함께 생성되도록 만들어야 한다.
C# 언어로 컴파일된 실행 파일에도 메타데이터가 담겨있다.
다른 사람이 만든 실행 파일에서 어떤 클래스와 메서드가 제공되는지 이 메타데이터를 통해 알 수 있다.
어셈블리, 모듈, 메니페스트
C#으로는 윈도우 환경에서 프로그램을 만드는 경우, 대개 EXE 또는 DLL 파일을 만들게 된다.
닷넷에서는 이런 실행 파일을 어셈블리(Assembly)라고 한다.
- 기계어와 1:1 대응되는 프로그래밍 언어인 어셈블리와 이름이 같아 혼동할 수 있지만, 닷넷 프록래밍에서 특별한 언급이 없다면 어셈블리는 실행 파일을 의미한다.
어셈블리는 1개 이상의 모듈로 구성되는데, 이때 모듈 하나당 한 개의 파일이 대응된다.
여러 개의 파일이 하나의 어셈블리를 구성하고 있다면 그 목록을 관리하는 데이터가 존재해야 한다.
이를 위해 모듈 중 하나는 반드시 다른 모듈의 목록을 관리하는 메니페시트(Manifest) 데이터를 담고 있어야 한다.
3개의 모듈로 구성된 어셈블리의 예시
- 메니페스트를 포함하고 있지 않은 모듈은 보통 확장자가 netmodule이다.
- 메니페시트를 포함하고 있는 확장자는 DLL 혹은 EXE이다.
- 어셈블리는 그 자체가 '참조 단위'이자 '배포 단위'라는 것에 의미가 있다.
- 다른 사람이 만든 어셈블리에 구현된 코드를 사용하고 싶다면 매니페스트가 포함된 모듈 및 그와 관련된 모듈을 함께 가지고 있어야 한다.
- 이론상 어셈블리가 다수의 모듈을 지원하긴 하지만, 일반적으로 개발하고나 사용하게 될 거의 모든 어셈블리가 1개의 실행 파일로 구성된다.
- 여러 개의 모듈을 관리하는 것은 번거롭고 비주얼 스튜디오 같은 개발 도구에서도 모듈 생성을 지원하지 않기 때문에 하나의 어셈블리 내에 다중 모듈을 사용하는 경우는 거의 없다.
공용 언어 기반구조
공용 언어 기반구조(Common Language Infrastructure)은 마이크로소프트에서 ECMA 표준으로 제출한 공개 규약
CLI는 CTS 명세를 포함하며, 중간 언어에 대한 코드 정의, 메타데이터와 그것을 포함하는 이진 파일(binary file)의 구조까지 표준 사양으로 기술하고 있다. 자바의 VM을 IBM과 오라클에서 구현한 것처럼 공개된 CLI 사양은 누구나 가져가서 임의로 구현 가능
IBM이 만든 JVM 위에서 컴파일된 자바 클래스 파일이 오라클 JVM 위에서 동작하는 것처럼 CLI 사양을 준수한 구현체에서 동작하는 닷넷 파일은 또 다른 구현체에서 실행하는 것이 가능
CLI 규격을 마이크로소프트에서 구현한 실체가 .NET Runtime이다.
과거 CLR(Common Language Runtime)이라는 CLI 구현체를 만들었지만, 윈도우환경에서만 실행된다는 제약으로 발전하지 못했다. 또 다른 구현체인 모노(MONO) 런타임은 오픈소스로 다중 플랫폼 지원을 목표로 활약했지만, 마이크로소프트가 새롭게 개발한 CoreCLR 구현체가 다중 플랫폼을 지원하면서 그 자리를 대체했다.
현재는 CoreCLR이 이름을 바꿔 .NETRuntime이라는 정식 명칭으로 사용됨.
공용 언어 런타임(CLR : Common Language Runtime)
과거 닷넷 프레임워크가 구현한 CLR은 CLI 사양을 따르는 가장 대표적인 VM이었다.
닷넷 코어가 나오면서 CLR을 다중 플랫폼에 맞게 재구현한 CoreCLR이나왔다. 이러한 CRL에는 두 가지 큰 기능이 있다.
- 중간 언어를 JIT 컴파일러를 이용해 기계어로 변환할 수 있다.
- 가비지 수집기(GC: Garbage Collector)를 제공해 동적 메모리 할당 및 회수를 지원하는 것이다.
CLR 자체를 관리 환경(Managed Environment)이라고도 하고, CLR이 로드되는 프로세스를 기존의 네이티브 프로세스와 구별해 관리 프로세스(Managed Process)라고 한다.
- 대체로 '관리'라는 단어가 들어가면 CLR 환경과 엮인다고 보면 된다. 닷넷 호환 언어 역시 C/C++ 언어와 같은 네이티브 언어와 구분하라는 의미에서 관리 언어(Managed Language)라고 한다.
CLI와 CLR/CoreCLR, 닷넷은 보통 구분 없이 사용된다는 점을 유의
ex) C#과 같은 언어는 닷넷 호환 언어라는 말보다 CLI 호환 언어라고 불려야 하는 것이 맞다.
단지 CLI 구현체 중에 CLR/CoreCLR이 대표적이고, 그중에서 Core CLR은 닷넷 제품에 포함되어 있기 때문에 암묵적으로 혼용하는 면이 있다.
닷넷
CLR말고도 여러 가지 구성 요소를 함께 만들어 하나의 패키지로 묶어 배포하는데 이것이 닷넷이다.
닷넷 = CoreCLR + 부가 구성 요소 라고 간단히 정의할 수 있다.
구성 요소
- BCL(Base Class Library) : 마이크로소프트는 특정 기능을 수행하는 타입을 미리 만들어 놓았으며 개발자는 이 기능을 이용해 좀 더 쉽게 응용 프로그램을 개발할 수 있다. ex) 문자열을 암호화해야 할 때 개발자가 직접 구현할 필요 없이 BCL에서 제공되는 암호화 관련 타입을 이용하면 된다.
- 기타 파일 : 닷넷 배포 버전에 맞는 디버그용 모듈과 실행중인 프로세스 메모리 덤프를 뜰 수 있는 createdump.exe 등을 함께 제공하며 부가적으로 닷넷 SDK 제품에는 닷넷 응용 프로그램 개발을 위한 c# 컴파일러 및 빌드 시스템을 포함해 배포하고 있다.
닷넷 응용프로그램을 계층상으로 나눈 이미지
닷넷 응용 프로그램은 기존의 모든 윈도우 응용 프로그램에 대응해서 만들 수 있다.
Visual C++롬 만든 네이티브 프로그램이 있다면 닷넷으로도 제작 가능
거의 모든 응용 프로그램에서 BCL을 사용하게 된다.
ex)파일을 만들어야 할 때 운영체제가 제공하는 API를 직접 호출하는 것도 가능하지만 BCL을 사용하면 더욱 편리하게 작업할 수 있다. BCL에는 개발자가 필요로 하는 많은 기능이 구현되어 있고 BCL을 공부해둘 필요가 있다.
새로운 버전이 출시될 때 마다 BCL의 영역은 더 커진다. → 배울 것이 많아진다, 개발자가 작성해야 할 코두의 규모는 상대적으로 줄어들고 있다는 의미이다.
닷넷 응용 프로그램을 만들려면 필연적으로 닷넷 환경의 전반적인 지식을 공부해야 하며, 그 지식에는 CLI/ CTS/ CIL이 포함되며, 많이 알 수록 닷넷 프로그램 제작능력이 향상될 것
C#과 닷넷의 관계
C#은 닷넷 환경을 위한 IL 코드를 생성하는 컴파일러에 불과하다.
F#은 MS에서 공식적으로 지원하는 닷넷의 함수형 언어이다.
닷넷 버전 | 닷넷의 변화 | C#의 변화 |
1.0~1.1 | '닷넷 코어'로 명명 | C# 6.0 |
2.0~2.2 | C# 7.x | |
3.0~3.1 | C# 8.0 | |
5.0 | '닷넷 코어'에서 '닷넷'으로 이름 변경 | C# 9.0 |
6.0 | C# 10 | |
7.0 | C# 11 | |
8.0 | C# 12 |
MS는 .Net을 출시하면서 그것을 가장 잘 표현할 수 있는 언어가 필요했고, 그렇게 해서 새롭게 탄생한 언어가 C#이다. C#은 .Net을 위해 태어났고 .Net과 함께 발전해 간다.
닷넷 프레임워크, 닷넷 코어와 닷넷 표준
- .NET FrameWork는 가장 첫번째 .NET 제픔으로 오직 윈도우 운영체제에서만 동작 가능하다는 제한을 가지고 있따. 하지만 윈도우 운영체제에 기본적으로 설치되어 있으므로 윈도우만을 대상으로 한 작고 가벼운 응용 프로그램을 개발하는 용도로 권장할 수 잇따.
- .Net Core는 .NET이라고 불리기 이전의 이름으로 .NET FrameWork와 달리 다중 플랫폼(Mac, Linux)등에서 실행할 수 있도록 만들어 졌다는 것이 강점이다.
- 기존의 오픈 소스로 운영되었던 Mono FrameWork가 다중 플랫폼을 지원했긴 했지만, 체계적이지 않은 면이 있는데다 점점 다중 플랫폼에서의 실행 환경이 중요해지면서 만들어 진 것이 .NET Core이다.
- .NET Core의 CLI 구현과 관련해 기반 소스코드를 .NET FrameWork와 공유해 Mono와는 다른 안정성과 성능으로 차별화
- 소스코드를 완전히 공개했고 이를 GitHub를 통해 외부 개발자와 협업해 더욱 빠른 개발 속도와 함께 다중 플랫폼으로의 포팅을 꾀하고있다.
- 다중 플랫폼 지원이라는 장점의 이면에는 특정 플랫폼에서만 실행 가능한 기능을 지원할 수 없다는 단점이 수반된다.
- 이는 자연스럽게 기반 라이브러리가 달라진다는 문제점을 야기한다.
- 실제로 .NET Core와 .NET FrameWork는 하부 구조는 공유하지만, 기반 라이브러리 단계부터 독자적인 구현으로 이루어 진다.
기반 라이브러리가 각각 Base Class Library와 Core Library로 나뉘면서 이를 바탕으로 제작되는 라이브러리의 재사용 문제가 발생한다. ex) 압축 라이브러리를 만드는 개발자가 Core Library에서 제공하는 클래스를 사용하면 해당 DLL은 .NET FrameWork용 응용 프로그램에서는 가져다 쓸 수 없는 문제 발생
→ 이 같은 기반 라이브러리의 불일치를 해결하기 위해 다시 그들만의 표준을 만든 규격이 닷넷 표준(.NET Standard) 라이브러리
만들 라이브러리가 적어도 닷넷 표준 라이브러리 위에서 만들어 졌다면 아무런 변경 없이 .NET Core와 .NET FrameWork 위에서 사용할 수 있게 보장해 주는 것이다. 하지만 .NET5가 나오면서 .NET Standard는 더 이상 의미가 없게 되었다.
닷넷으로 새롭게 명명
데스크톱용 닷넷 버전의 출시가 4.8이 마지막 -> 이후 닷넷 코어 기반으로 통합하기 위한 준비를 하며 실제로 닷넷 코어 3.0에서는 데스크톱 버전에서만 지원하던 Windows Form와 WPF 유형의 프로젝트 지원을 포함.
그 후 기존의 닷넷 프레임워크와 닷넷 코어라는 구분을 모두 없애고 "하나의 닷넷이라는 .Net 5" 버전 발표
현재는 .NET 9에 이르렀다.
.NET Core는 3.1을 마지막으로 더 이상 'Core'라는 단어를 사용하지 않는다. .NET FrameWork가 4.8 버전을 마지막으로 더 이상 업데이트 하지 않게 되었으므로 이후부터는 .NET5, .NET 6, .NET 7 과 같이 곧바로 .NET[버전 번호]의 형식으로 이름이 바뀌었다.
이 때문에 .NET Core어ㅣ .NET 5/6/7/8을 모두 일컬을 때 '.NET Core/5+라는 식으로 표기하거나 .NET 5/6/7/8만 가리킬 때는 .NET 5+라는 식으로 표기한다.
정식 명칭이 .NET으로 변경되면서 .NET 응용 프로그램을 실행하기 위한 패키지 제품의 이름을 '.NET Runtime'으로 배포하고 있으며 개발자를 위한 유틸리티 성격의 프로그램을 더해 .NET SDK로 배포하고 있다.
Reference
시작하세요! C# 12 프로그래밍 기본 문법부터 실전 예제까지
https://blog.naver.com/ya3344/223125448918
닷넷 프레임워크
닷넷 프레임워크 닷넷 프레임워크를 설치하면 가상 머신 역할을 하는 CLR 구성요소가 실행될 수 있는 환...
blog.naver.com
https://kukuta.tistory.com/351
[C#] IL(Intermediate Language)
IL(Intermediate Language) 여러분의 PC를 보면 CPU가 있을 것이고 그 위에 운영체제가 설치 되어있을 것이다. 만일 여러분이 C/C++과 같은 언어로 프로그램을 작성한 다음 컴파일 하면 실행가능한 실행 파
kukuta.tistory.com
https://kukuta.tistory.com/350
[C#] IL 디스어셈블러(ildasm.exe) 유틸리티
ildasm.exe란? IL 디스어셈블러(ildasm.exe)는 IL 어셈블러(ilasm.exe)의 자매도구로써 IL코드를 포함하고 있는 포터블 실행 파일(PE)을 이용해 ilasm.exe의 입력에 적합한 텍스트 파일을 생성한다. 다시 말하
kukuta.tistory.com
https://velog.io/@whdrnr545/C-C-9.0-1%EC%9E%A5-.NET-Framework
[C#] C# 9.0 .NET Framework
닷넷 프레임 워크 .NET Framework >일반적인 네이티브 언어로 만들어진 프로그램들이 운영체제에서 곧바로 실행되는 것과는 달리, 닷넷 프레임워크를 기반으로 만들어진 응용 프로그램은 반드시 닷
velog.io
https://devblogs.microsoft.com/dotnet/announcing-dotnet-9/
Announcing .NET 9 - .NET Blog
Announcing the release of .NET 9, the most productive, modern, secure, intelligent, and performant release of .NET yet. With updates across ASP.NET Core, C#, .NET MAUI, .NET Aspire, and so much more.
devblogs.microsoft.com
'C#' 카테고리의 다른 글
C# [제어문] (0) | 2025.05.09 |
---|---|
C# [배열] (0) | 2025.05.07 |
C# [기본 문법 요소] (0) | 2025.05.07 |
C# [형 변환] (0) | 2025.05.05 |
C# [기본 자료형] (3) | 2025.05.04 |