메모
이 문서는 기능 사양입니다. 사양은 기능의 디자인 문서 역할을 합니다. 여기에는 기능 디자인 및 개발 중에 필요한 정보와 함께 제안된 사양 변경 내용이 포함됩니다. 이러한 문서는 제안된 사양 변경이 완료되고 현재 ECMA 사양에 통합될 때까지 게시됩니다.
기능 사양과 완료된 구현 간에 약간의 불일치가 있을 수 있습니다. 이러한 차이는 관련된 LDM(언어 디자인 모임) 노트에 기록됩니다.
규격문서에서 C# 언어 표준으로 기능 사양을 채택하는 과정에 대해 자세히 알아볼 수 있습니다.
챔피언 이슈: https://github.com/dotnet/csharplang/issues/6065
요약
이는 nint
/nuint
형식이 System.IntPtr
/System.UIntPtr
기본 형식과 구별되는 초기 네이티브 정수 기능(사양)에 대한 수정 버전입니다.
요컨대, 이제 nint
/nuint
System.Int32
관련하여 int
경우처럼 System.IntPtr
/System.UIntPtr
별칭을 지정하는 간단한 형식으로 취급합니다.
System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr
런타임 기능 플래그는 이 새로운 동작을 트리거합니다.
디자인
8.3.5 단순 형식
C#은 단순 형식이라는 미리 정의된 struct
형식 집합을 제공합니다. 단순 형식은 키워드를 통해 식별되지만 이러한 키워드는 아래 표에 설명된 대로 System
네임스페이스의 미리 정의된 struct
형식에 대한 별칭일 뿐입니다.
키워드 | 별칭 형식 |
---|---|
sbyte |
System.SByte |
byte |
System.Byte |
short |
System.Int16 |
ushort |
System.UInt16 |
int |
System.Int32 |
uint |
System.UInt32 |
nint |
System.IntPtr |
nuint |
System.UIntPtr |
long |
System.Int64 |
ulong |
System.UInt64 |
char |
System.Char |
float |
System.Single |
double |
System.Double |
bool |
System.Boolean |
decimal |
System.Decimal |
[...]
8.3.6 정수 계열 형식
C#은 sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
등 11개의 정수 계열 형식을 지원합니다. [...]
8.8 관리되지 않는 형식
즉, unmanaged_type 다음 중 하나입니다.
-
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
,decimal
또는bool
. - 모든 열거형 타입 .
- 구성된 형식이 아니며 오직 unmanaged_type필드만 포함하는 사용자 정의 struct_type.
- 안전하지 않은 코드에서는 pointer_type.
10.2.3 암시적 숫자 변환
암시적 숫자 변환은 다음과 같습니다.
-
sbyte
에서short
,int
,nint
,long
,float
,double
또는decimal
. -
byte
에서short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,float
,double
또는decimal
. -
short
부터int
,nint
,long
,float
,double
또는decimal
까지. -
ushort
에서int
,uint
,nint
,nuint
,long
,ulong
,float
,double
또는decimal
. -
int
에서nint
,long
,float
,double
또는decimal
. -
uint
부터nuint
,long
,ulong
,float
,double
또는decimal
까지. -
nint
에서long
,float
,double
또는decimal
. -
nuint
에서ulong
,float
,double
또는decimal
. -
long
에서float
,double
또는decimal
로. -
ulong
에서float
,double
또는decimal
. -
char
에서ushort
,int
,uint
,nint
,nuint
,long
,ulong
,float
,double
또는decimal
. -
float
부터double
.
[...]
10.2.11 암시적 상수 식 변환
암시적 상수 식 변환은 다음과 같은 변환을 허용합니다.
-
constant_expression 값이 대상 형식 범위 내에 있는 경우 형식
int
constant_expression 형식sbyte
,byte
,short
,ushort
,uint
,nint
,nuint
또는ulong
변환할 수 있습니다. [...]
10.3.2 명시적 숫자 변환
명시적 숫자 변환은 numeric_type을 numeric_type으로 변환하는 것을 의미하며, 이는 암시적 숫자 변환이 존재하지 않는 경우입니다.
-
sbyte
에서byte
,ushort
,uint
,nuint
,ulong
또는char
으로. -
byte
부터sbyte
또는char
. -
short
에서sbyte
,byte
,ushort
,uint
,nuint
,ulong
또는char
. -
ushort
에서sbyte
,byte
,short
또는char
까지. -
int
에서sbyte
,byte
,short
,ushort
,uint
,nuint
,ulong
또는char
. -
uint
에서sbyte
,byte
,short
,ushort
,int
,nint
또는char
. -
long
에서sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,ulong
또는char
. -
nint
에서sbyte
,byte
,short
,ushort
,int
,uint
,nuint
,ulong
또는char
. -
nuint
에서sbyte
,byte
,short
,ushort
,int
,uint
,nint
,long
또는char
. -
ulong
에서sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
또는char
. -
char
부터sbyte
,byte
또는short
. -
float
에서sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
또는decimal
. -
double
에서sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
또는decimal
. -
decimal
에서sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
또는double
.
[...]
10.3.3 명시적 열거형 변환
명시적 열거형 변환은 다음과 같습니다.
-
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
또는decimal
에서 임의의 enum_type로. - 어떤 enum_type 에서
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
또는decimal
로. - enum_type에서 다른 enum_type로.
12.6.4.7 더 나은 변환 대상
두 가지 형식 T₁
및 T₂
이 주어졌을 때, T₁
는 더 나은 변환 대상이 될 수 있습니다. 다음 중 하나가 성립하면: T₂
.
-
T₁
T₂
암시적 변환이 존재하며T₂
T₁
암시적 변환이 없습니다. -
T₁
은Task<S₁>
이고,T₂
은Task<S₂>
이며,S₁
는S₂
보다 더 나은 변환 대상입니다. -
T₁
는S₁
또는S₁?
이며,S₁
는 부호 있는 정수형입니다. 그리고T₂
는S₂
또는S₂?
이며,S₂
는 부호 없는 정수형입니다. 구체적으로: [...]
12.8.12 요소 액세스
[...] argument_list 식 수는 array_type순위와 같아야 하며 각 식은 int
, uint
, nint
, nuint
, long
또는 ulong,
형식이거나 이러한 형식 중 하나 이상으로 암시적으로 변환할 수 있어야 합니다.
11.8.12.2 배열 액세스
[...] argument_list 식 수는 array_type순위와 같아야 하며 각 식은 int
, uint
, nint
, nuint
, long
또는 ulong,
형식이거나 이러한 형식 중 하나 이상으로 암시적으로 변환할 수 있어야 합니다.
[...] P[A]
형식 배열 접근의 런타임 처리는 P
이 primary_no_array_creation_expression의 array_type이고 A
이 argument_list인 경우, 다음 단계로 구성됩니다. [...]
-
argument_list 인덱스 식은 왼쪽에서 오른쪽으로 순서대로 평가됩니다. 각 인덱스 식을 평가한 후에는
int
,uint
,nint
,nuint
,long
,ulong
중 하나로 암시적으로 변환됩니다. 암시적 변환이 존재하는 이 목록의 첫 번째 형식이 선택됩니다. [...]
12.8.16 후위 증가 및 감소 연산자
단항 연산자 오버로드 확인은 특정 연산자 구현을 선택하기 위해 적용됩니다. 미리 정의된 ++
및 --
연산자는 sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
,long
, ulong
, char
, float
, double
, decimal
및 모든 열거형 형식에 대해 존재합니다.
12.9.2 단항 더하기 연산자
미리 정의된 단항 더하기 연산자는 다음과 같습니다.
...
nint operator +(nint x);
nuint operator +(nuint x);
12.9.3 단항 빼기 연산자
미리 정의된 단항 빼기 연산자는 다음과 같습니다.
정수 부정:
... nint operator –(nint x);
12.8.16 후위 증가 및 감소 연산자
미리 정의된 ++
및 --
연산자는 sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
및 모든 열거형 형식에 대해 존재합니다.
11.7.19 기본값 식
또한 형식이 sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
, bool,
또는 열거형 형식 중 하나이면 default_value_expression 상수 식입니다.
12.9.5 비트 반전 연산자
미리 정의된 비트 보수 연산자는 다음과 같습니다.
...
nint operator ~(nint x);
nuint operator ~(nuint x);
12.9.6 접두사 증가 및 감소 연산자
미리 정의된 ++
및 --
연산자는 sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
및 모든 열거형 형식에 대해 존재합니다.
12.10 산술 연산자
12.10.2 곱하기 연산자
미리 정의된 곱셈 연산자는 아래에 나열되어 있습니다. 연산자는 모두 x
및 y
곱을 계산합니다.
정수 곱하기:
... nint operator *(nint x, nint y); nuint operator *(nuint x, nuint y);
12.10.3 나눗셈 연산자
미리 정의된 나누기 연산자는 다음과 같습니다. 연산자는 모두 x
및 y
몫을 계산합니다.
정수 나누기:
... nint operator /(nint x, nint y); nuint operator /(nuint x, nuint y);
12.10.4 나머지 연산자
미리 정의된 나머지 연산자는 아래에 나열되어 있습니다. 연산자는 모두 x
y
사이의 나머지 부분을 계산합니다.
정수 나머지:
... nint operator %(nint x, nint y); nuint operator %(nuint x, nuint y);
12.10.5 더하기 연산자
정수 추가:
... nint operator +(nint x, nint y); nuint operator +(nuint x, nuint y);
12.10.6 빼기 연산자
정수 빼기:
... nint operator –(nint x, nint y); nuint operator –(nuint x, nuint y);
12.11 시프트 연산자
미리 정의된 시프트 연산자는 아래에 나열되어 있습니다.
왼쪽으로 이동:
... nint operator <<(nint x, int count); nuint operator <<(nuint x, int count);
오른쪽으로 이동:
... nint operator >>(nint x, int count); nuint operator >>(nuint x, int count);
>>
연산자는 아래 설명된 대로 계산된 비트 수만큼x
오른쪽으로 이동합니다.x
형식이int
,nint
또는long
경우 낮은 순서의x
비트가 삭제되고, 나머지 비트는 오른쪽으로 이동하고,x
음수가 아니면 상위 빈 비트 위치가 0으로 설정되고x
음수이면 1로 설정됩니다.x
형식이uint
,nuint
또는ulong
경우 낮은 순서의x
비트가 삭제되고, 나머지 비트가 오른쪽으로 이동되고, 상위 빈 비트 위치가 0으로 설정됩니다.서명되지 않은 시프트 오른쪽:
... nint operator >>>(nint x, int count); nuint operator >>>(nuint x, int count);
미리 정의된 연산자의 경우 이동할 비트 수는 다음과 같이 계산됩니다. [...]
-
x
유형이nint
또는nuint
시프트 수는 32비트 플랫폼의 하위 5비트count
또는 64비트 플랫폼의 하위 6비트count
의해 제공됩니다.
12.12 관계형 및 형식 테스트 연산자
12.12.2 정수 비교 연산자
미리 정의된 정수 비교 연산자는 다음과 같습니다.
...
bool operator ==(nint x, nint y);
bool operator ==(nuint x, nuint y);
bool operator !=(nint x, nint y);
bool operator !=(nuint x, nuint y);
bool operator <(nint x, nint y);
bool operator <(nuint x, nuint y);
bool operator >(nint x, nint y);
bool operator >(nuint x, nuint y);
bool operator <=(nint x, nint y);
bool operator <=(nuint x, nuint y);
bool operator >=(nint x, nint y);
bool operator >=(nuint x, nuint y);
12.12 논리 연산자
12.12.2 정수 논리 연산자
미리 정의된 정수 논리 연산자는 다음과 같습니다.
...
nint operator &(nint x, nint y);
nuint operator &(nuint x, nuint y);
nint operator |(nint x, nint y);
nuint operator |(nuint x, nuint y);
nint operator ^(nint x, nint y);
nuint operator ^(nuint x, nuint y);
12.22 상수 식
상수 식은 값 형식 또는 참조 형식일 수 있습니다. 상수 식이 값 형식인 경우 sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
, bool,
또는 열거형 형식 중 하나여야 합니다.
[...]
암시적 상수 식 변환을 사용하면 상수 식의 값이 대상 형식 범위 내에 있는 경우 sbyte
, int
byte
, short
, ushort
, uint
, nint
, nuint
, 또는 ulong
형식의 상수 식을 변환할 수 있습니다.
17.4 배열 요소 접근
배열 요소는 A[I₁, I₂, ..., Iₓ]
양식의 element_access 식을 사용하여 액세스합니다. 여기서 A
배열 형식의 식이고 각 Iₑ
int
, uint
, nint
, nuint
,long
, ulong
형식의 식이거나 이러한 형식 중 하나 이상으로 암시적으로 변환될 수 있습니다. 배열 요소 액세스의 결과는 변수, 즉 인덱스에 의해 선택된 배열 요소입니다.
23.5 포인터 변환
23.5.1 일반
[...]
또한 안전하지 않은 컨텍스트에서는 다음과 같은 명시적 포인터 변환을 포함하도록 사용 가능한 명시적 변환 집합이 확장됩니다.
- 어떠한 pointer_type에서 다른 pointer_type로.
-
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
, 또는ulong
에서 pointer_type로. - 모든 pointer_type에서,
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
또는ulong
으로.
23.6.4 포인터 요소 액세스
[...] P[E]
폼의 포인터 요소 액세스에서 P
void*
이외의 포인터 형식의 식이어야 하며, E
int
, uint
, nint
, nuint
,long
또는 ulong
암시적으로 변환할 수 있는 식이어야 합니다.
23.6.7 포인터 산술 연산
안전하지 않은 컨텍스트에서 +
연산자와 –
연산자는 void*
제외한 모든 포인터 형식의 값에 적용할 수 있습니다. 따라서 T*
모든 포인터 형식에 대해 다음 연산자가 암시적으로 정의됩니다.
[...]
T* operator +(T* x, nint y);
T* operator +(T* x, nuint y);
T* operator +(nint x, T* y);
T* operator +(nuint x, T* y);
T* operator -(T* x, nint y);
T* operator -(T* x, nuint y);
포인터 형식 T*
의 표현식 P
와 int
, uint
, nint
, nuint
,long
, 또는 ulong
형식의 표현식 N
가 주어졌을 때, 표현식 P + N
과 N + P
는 P
로 지정된 주소에 N * sizeof(T)
를 더한 결과로 T*
형식의 포인터 값을 계산합니다. 마찬가지로 식 P – N
P
지정한 주소에서 N * sizeof(T)
빼서 발생하는 T*
형식의 포인터 값을 계산합니다.
다양한 고려 사항
주요 변경 내용
이 디자인의 주요 영향 중 하나는 System.IntPtr
및 System.UIntPtr
일부 기본 제공 연산자(변환, 단항 및 이진)를 얻을 수 있다는 것입니다.
여기에는 checked
연산자가 포함됩니다. 즉, 해당 형식에서 다음 연산자는 오버플로될 때 예외를 던집니다.
IntPtr + int
IntPtr - int
IntPtr -> int
long -> IntPtr
void* -> IntPtr
메타데이터 인코딩
이 디자인은 System.Runtime.CompilerServices.NativeIntegerAttribute
사용하지 않고 nint
및 nuint
단순히 System.IntPtr
및 System.UIntPtr
내보낼 수 있음을 의미합니다.
마찬가지로 메타데이터 NativeIntegerAttribute
로드하는 경우 무시될 수 있습니다.
C# feature specifications