Loading AI tools
객체 지향 프로그래밍 언어 위키백과, 무료 백과사전
C#(한국어: 시 샤프 또는 C 샵)는 마이크로소프트에서 개발한 객체 지향 프로그래밍 언어로, 닷넷 프레임워크의 한 부분으로 만들어졌으며 나중에 ECMA (ECMA-334)와 ISO (ISO/IEC/23270)의 표준으로 자리잡았다. C++와 자바의 문법과 비슷한 문법을 가지고 있다.
패러다임 | 프로그래밍 패러다임: 구조적 프로그래밍, 명령형 프로그래밍, 객체 지향 프로그래밍, 사건 기반 프로그래밍, 비동기 메서드 호출, 함수형 프로그래밍, 제네릭 프로그래밍, 반영, 병행 컴퓨팅 |
---|---|
설계자 | 마이크로소프트 |
개발자 | 마이크로소프트 |
발표일 | 2000년 |
최근 버전 | 12.0[1] |
최근 버전 출시일 | 2023년 11월 14일 |
플랫폼 | 공통 언어 기반(CLI) |
라이선스 | CLR: MIT 라이선스 모노 컴파일러: GPLv3&MIT 라이선스 라이브러리: LGPLv2 |
파일 확장자 | .cs |
웹사이트 | docs |
주요 구현체 | |
비주얼 C 샤프, 닷넷 프레임워크, 모노, 던GNU | |
Cω, 스페이스 샤프, 폴리포닉 C 샤프, 엔터헤드 C# | |
영향을 받은 언어 | |
C++, 에펠, 자바, 모델-3, 오브젝트 파스칼, ML, VB, 아이콘, 하스켈, 러스트, J#, Cω, F# | |
영향을 준 언어 | |
체펠, D, J#, 해키, 자바, 코틀린, 몽키 X, 네메레, 옥시즌, 러스트, 스위프트, 발라 |
using System; //System이라는 모듈을 사용한다. 해당 모듈은 Console에 관한것들을 담고있다
namespace HelloWorld
{ //namespace를 정의한다. 자바로 치면 패키지나 프로젝트라고 생각하면 된다
class Program
{ //클래스를 시작한다. 자바의 클래스와 같다고 생각하면 된다.
private static void Main()
{ //private이라는 구문으로 클래스 내부에서만 가능하게 만든다. static void Main()이라는 구문으로 메인 메소드를 만든다. 이것은 Java 와 다르고 C 와 C++처럼 (string[] args) 가 붙지 않으며 보통 빈칸이다.
Console.WriteLine("Hello, World!"); //콘솔에 하얀색 글씨로 Hello World 라고 출력한다.
Console.ReadLine(); //그냥 WriteLine 이라고 쓰면 바로 프로그램이 종료된다. ReadLine으로 아무키나 눌러야 종료되도록 한다.
} //메인메소드의 끝. 메소드의 끝이라고 할 수 있다.
} //클래스의 끝. 클래스밑에 다른 클래스를 만들수 없다
} //네임스페이스의 끝. 폴더의 끝이라고 생각하면 된다
System.Console.WriteLine("Hello, World!");
//System 구문으로 System 을 사용한다는 정의와 동시에 namespace 없이 작동시킨다
//Console 구문으로 콘솔을 출력한다
//WriteLine으로 하얀색 글을 콘솔에 붙인다.
C#은 마이크로소프트 닷넷 프로그램이 동작하는 닷넷 플랫폼을 가장 직접적으로 반영하고, 또한 닷넷 플랫폼에 강하게 의존하는 프로그래밍 언어이다. C#은 그 문법적인 특성이 자바와 상당히 유사하며 C#을 통하여 다룰 수 있는 닷넷 플랫폼의 기술들조차도 자바를 염두에 둔 것이 많아서 자바와 가장 많이 비교되고 있다. 하지만 C#은 자바와 달리 불안전 코드(unsafe code)[4]와 같은 기술을 통하여 플랫폼 간 상호 운용성에 상당히 많은 노력을 기울이고 있다. C#의 기본 자료형은 닷넷의 객체 모델을 따르고 있고, 런타임 차원에서 쓰레기 수집(garbage collection)이 되며 또한 클래스, 인터페이스, 위임, 예외와 같이 객체 지향 언어로서 가져야 할 모든 요소들이 포함되어 있다.
닷넷 프레임워크를 개발하던 시절 클래스 라이브러리는 SMC(Simple Managed C)라 불리는 관리 코드(managed code)를 사용했었다.[5] 1999년 1월, 아네르스 하일스베르가 이끄는 팀이 새로운 언어인 Cool(C-like Object Oriented Language)을 개발했다. 마이크로소프트는 언어의 최종 이름을 Cool로 유지할지도 고려해봤지만 상표 문제로 인해 이뤄지지 않았다. 2000년 7월 PDC에서 닷넷 프로젝트가 발표될 때 즈음 Cool의 이름은 C#으로 정해졌고 클래스 라이브러리와 ASP.NET 런타임은 C#으로 옮겨갔다.
C#은 ISO 소위원회 JTC 1/SC 22에 ISO/IEC 23270:2003으로 제출되었으나 철회 후 ISO/IEC 23270:2006으로 등록되었다.
C#이라는 이름은 음표를 연주할 때 반음 올리는 것을 표시하는 올림표에서 따왔다. C++에서 "++"가 변수의 값을 1 증가시키는 것을 의미하는 것과 비슷하다. 마찬가지로 올림표는 네 개의 "+" 기호와 비슷하므로 C++를 한번 더 증가시켰다는 뜻도 지닌다.
기본 글꼴이나 브라우저의 기술적인 한계와 더불어 키보드에는 올림표 기호(U+266F ♯ )가 포함되지 않기에 문서에서는 대체 기호로 해시 기호(U+0023 # )를 사용하며, ECMA-334 C# 언어 사양[6] 에서도 확인할 수 있다. 그러나 광고나 패키지 포장 등 가능한 경우, 마이크로소프트에서는 의도한 대로 올림표를 사용한다.
버전 | 언어 사양 | 날짜 | 닷넷 프레임워크 | 비주얼 스튜디오 | ||
---|---|---|---|---|---|---|
ECMA | ISO/IEC | 마이크로소프트 | ||||
C# 1.0 | 2002년 12월 | 2003년 4월 | 2002년 1월 | 2002년 1월 | .NET Framework 1.0 | 비주얼 스튜디오 .NET 2002 |
C# 1.2 | 2003년 10월 | 2003년 4월 | .NET Framework 1.1 | 비주얼 스튜디오 .NET 2002 | ||
C# 2.0 | 2006년 6월 | 2006년 9월 | 2005년 9월 | 2005년 11월 | .NET Framework 2.0 | 비주얼 스튜디오 2005 |
C# 3.0 | 없음[note 1] | 2007년 8월 | 2007년 11월 |
.NET Framework 2.0 (LINQ/쿼리 확장 제외)[7]
|
비주얼 스튜디오 2008 | |
C# 4.0 | 2010년 4월 | 2010년 4월 | .NET Framework 4.0 | 비주얼 스튜디오 2010 | ||
C# 5.0 | 2017년 12월 | 2018년 12월 | 2013년 6월 | 2012년 8월 | .NET Framework 4.5 | 비주얼 스튜디오 2012 |
C# 6.0 | 없음[note 1] | 없음 | 2015년 7월 | .NET Framework 4.6 | 비주얼 스튜디오 2015 | |
C# 7.0 | 2017년 5월 | .NET Framework 4.7 | 비주얼 스튜디오 2017 |
C#의 기본 문법은 C, C++, 자바 등 C 스타일 언어와 유사하다.
C++ 언어와 비교할 때 C#은 다음과 같은 점에서 단순화되거나 확장되었다.
bool
은 오직 true
와 false
의 논리값만을 가질 수 있으며,상수 또는 정수형 변수에서 암시적으로 변환이 불가능하다. 직접 대입을 위해서는 변환 명령을 이용해야 한다. 반면 C++의 bool
은 정수값을 대입할 수 있다. 또한 C#에서는 if
나 while
문 등의 비교문에서 이용하는 값도 bool
형태로 제한되는 반면, C++에서는 상수 또는 변수를 이용하여 '0이 아닌 값' 또는 '0'의 여부로 비교할 수 있다.static
키워드를 오직 한 번만 초기화를 수행한다는 의미로 이용할 수 없다./unsafe
또는 --unsafe
스위치를 지정하도록 명시해야 한다. unsafe 블록의 사용 예는 다음과 같다.unsafe { int *pA; }
System.IntPtr
이다.(System.UIntPtr
은 특수한 목적으로 쓰이므로 설명에서 제외한다.)
(IntPtr.ToPointer
메서드로 void*
형식을 가져올 수 있음)도 지원한다.
C++에서 포인터는 특정한 형식의 인스턴스 또는 주소값을 가리키기 위한 목적으로 할당되는 주소값을 기억하기 위한 변수로 취급되지만
C#의 포인터는 System.IntPtr
이라는 하나의 완성된 형식에 대한 확장 사양일 뿐이다.
그래서 C++의 포인터와 같은 쓰임새를 C#으로 이식할 수 없는 경우가 상당히 많다.
void*
포인터가 가리키는 값을 얻어낼 수 없고 void*
포인터에 대한 산술 연산도 수행할 수 없다./checked+
로 지정된 경우모든 코드 범위에서 엄격한 산술 연산 검사를 할 수 있으며 /checked-
로 지정된 경우
모든 코드 범위에서 산술 연산 검사를 하지 않도록 할 수 있다.
컴파일러 옵션과는 관계없이 unchecked 블록 안에서는 검사되지 않으며,
반대로 checked 블록 안에서는 검사가 이루어진다.
int a = 0; unchecked { a = int.MaxValue + 20; } checked { a = int.MaxValue * 2; }
using System; namespace FooBar { class Program { private int Test = 123; static void Main(string[] args) { unsafe { Program p = new Program(); fixed (int* ptrX = &p.Test) { Console.Out.Write(Convert.ToString(*ptrX)); *ptrX = 21; Console.Out.WriteLine(Convert.ToString(*ptrX)); } } } } }
IDisposable
인터페이스를 특정 클래스에서 구현하게 된다. IDisposable
인터페이스를 구현하는 클래스는 C#의 using 구문을 이용하여 자동으로 IDisposable.Dispose
메서드를 호출할 수도 있다.System.Object
클래스가 모든 클래스의 선조 클래스이기 때문에 이러한 관대함이 가능하게 되었다. (단, unsafe 블록 내에서 사용되는 포인터 형식의 경우는 예외로 한다.)int*, void*, byte*
, ...와 같이 하나의 완성된 형식으로서 이해할 수 있지만 C++은 메모리 주소값을 저장하도록 되어있는 형태이다. 포인터를 사용하고자 하는 목적은 같지만 C++에서처럼 어떤 곳에서나 주소를 참조할 수 있는 것은 아니므로 정확한 이해가 필요하다. (다만, 특수한 GCHandle
형식을 활용하여 Pinned Object를 생성하는 경우에는 이러한 접근이 가능할 수 있으나 특성에 맞지도 않으며 심각한 성능 저하를 일으키므로 좋은 방법이라고 할 수 없을것이다.)// C# int[] a = new int[5]; int* pA, pB;// C++ int a[5]; int *pA, *pB;
get_foo()
메서드와 set_foo()
메서드로 구분되어 표현되곤 한다.public string Name { get { return m_name; } set { m_name = "Name :: "+value; } } public void MethodOne(string name) { this.Name = "DotNet"; }
C#에서 리플렉션으로 확장하여 사용하는 것이 가능하다. 리플렉션은 자바 언어의 리플렉션과 같은 개념이다.
즉, C/C++에서 사용되던 #include나 #pragma와 같은 지시자를 C#에서는 사용할 수 없으며, C/C++에서 매크로 상수나 매크로 함수 등을 위해 사용되던 #define이 C#에서는 매우 제한적인 용도로 사용된다. 또한 C/C++에는 없던 #region, #endregion 지시자가 새로 추가되었다. 예를 들면 다음과 같다.
#define CsDebug
#region 아래는 FooClass 선언입니다.
public class FooClass
{
private int integer;
#if CsDebug
private string debugmsg;
#endif
public string DebugMsg
{
get
{
#if CsDebug
return this.debugmsg;
#else
return null;
#endif
}
set
{
#if CsDebug
this.debugmsg = value.Clone() as string;
#endif
}
}
}
#endregion
즉, 모든 인스턴스나 메서드는 반드시 특정 클래스의 멤버로 소속되어야 한다.
대신 C# 3.0부터 이와 비슷한 확장 메서드를 지원하고 있다. 확장 메서드는 정적 클래스의 멤버로 있어야 하며 이 때에도 대상 클래스의 private 멤버에는 접근 할 수 없다.
public class Foo
{
[MarshalAs(UnmanagedType.U4)]
private uint dwValue;
[MarshalAs(UnmanagedType.LPWstr)]
private string lpcwValue;
public uint DWValue
{
get { return this.dwValue; }
set { this.dwValue = value; }
}
public string LPCWValue
{
get { return this.lpcwValue; }
set { this.lpcwValue = value.Clone() as string; }
}
}
public static class Bar
{
public static string FooString(this Foo foo)
{
return string.Format("정수 값은 {0}, 문자열 값은 {1}입니다.", foo.DWValue, foo.LPCWValue);
}
}
(이 부분은 C++11에서 auto 키워드로 지원한다. )
아래 예제는 정수형으로 이루어진 배열에서 100을 초과하는 값만을 추출하는 코드이다.
public List<int> linqtest(List<int> list)
{
var result = from k in list where k > 100 select k;
return result;
}
public static void Print(int a, int b, Func<int> func)
{
Console.WriteLine("{0} 더하기 {1}은 {2}입니다.", a, b, func(a, b));
}
public static void Main()
{
Print(a, b, f => {Console.WriteLine("func가 호출되었습니다."); return a+b;});
}
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.