1.0이 아닌 열거 형 값에 0.0을 할당 할 수있는 이유
호기심 때문입니다. 왜 1.0이 아닌 열거 유형의 변수에 0.0을 할당 할 수 있습니까? 다음 코드를 사용합니다.
public enum Foo
{
Bar,
Baz
}
class Program
{
static void Main()
{
Foo value1 = 0.0;
Foo value2 = 1.0; // This line does not compile
Foo value3 = 4.2; // This line does not compile
}
}
숫자 유형과 열거 값 변환은 캐스트를 통해서만 허용된다고 생각했습니다. 즉, Foo를 작성 value2 = (Foo) 1.0;
하여 두 번째 줄 Main
을 만들 수 있습니다. 0.0
C # 의 값 에 예외가있는 이유는 무엇입니까?
0.0을 사용할 수 있습니다. 컴파일러는 값이 0 인 모든 상수 식을 암시 적으로 0으로 취급합니다.
이제 컴파일러가 C # 5 사양의 섹션 6.1.3에 따라 0 의 상수 식에서 열거-type으로 의 암시 적 CHAPTER 2을 허용하는 것이 옳 습니다 int
.
암시 적 열거 변환을 사용하면 decimal-integer-literal 0이 모든 열거 형 및 기본 형식이 열거 형인 nullable 형식으로 변환 될 수 있습니다. 후자의 경우 변환은 기본 열거 형 형식으로 변환하고 결과를 래핑하여 평가합니다 (§4.1.10).
이전에 C # 팀과 이야기를 나눴습니다. 우연히 0.0 (실제로 0.0m 및 0.0f)에서 열거 형 값으로 변환 하는 것을 제거하고 싶었지만 불행히도 코드가 너무 많이 사용 되었음에도 불구하고 애초에 허용되어 있습니다.
모노 mcs
는 있지만 컴파일러는, 부동 소수점 CHAPTER 2이을 모두 금지 않습니다 수 있습니다 :
const int Zero = 0;
...
SomeEnum x = Zero;
그것이 Zero
상수 표현이지만 십진 정수 리터럴이 아니라는 사실에도 불구하고 .
값이 0 인 정수 상수입니다 (예 : 모방 mcs
) 을 허용하도록 앞으로 C # 사양이 변경 될보고 놀라지 않을 것입니다 . 부동 소수점 CHAPTER 2 그러나이 공식적 으로 정확할 것이라고 기대하지는 않습니다 . (물론 C #의 미래를 예측하는 것에 대해 이전에 틀 렸습니다 ...)
Jon의 대답이 맞습니다. 나는 다음과 같은 점을 추가 할 것이다.
이 어리 석고 부끄러운 버그를 일 으세요. 많은 사과드립니다.
이 버그는 컴파일러에서 "expression is zero"술어의 의미를 오해하여 발생했습니다. 실제로 "이 유형의 기본값입니까?"라는 줄을 따라 더 많은 것을 검사 할 때 정수 0이 같음 만 검사한다고 믿었습니다. 사실, 이전 버전의 버그에서는 실제로 모든 유형의 기본값을 열거 형에 할당 할 수있었습니다! 이제는 숫자의 기본값 일뿐입니다. (강의 : 헬퍼 술어의 이름을 신중하게 지정하십시오.)
내가 엉망으로 구현하려고 시도한 동작은 사실 약간 다른 버그에 대한 해결 방법이었습니다. 여기에서 끔찍한 이야기 전체를 읽을 수 있습니다. http://blogs.msdn.com/b/ericlippert/archive/2006/03/28/the-root-of-all-evil-part-one.aspx 및 여기 http : //blogs.msdn.com/b/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx (강의 : 오래된 버그를 수정하면서 새로운 더 나쁜 버그를 도입하는 것은 매우 쉽습니다. 그들.)
C # 팀은 강력한 이점이없는 기존 코드를 손상시킬 위험이 너무 높기 때문에이 버그가있는 동작을 수정하기보다는 숨기기로 결정했습니다. (강의 : 처음부터 올바르게!)
이 동작을 보존하기 위해 Roslyn에서 작성한 코드는의 메서드
HasImplicitEnumerationConversion
에서 찾을 수 있습니다compilers\csharp\source\binder\semantics\conversions\conversions.cs
. Roslyn 동작이 정확히 무엇인지에 대한 자세한 내용은 참조하십시오. (주에게 나는 마음에 당신의 술어를 이름의 교훈을 걸렸다 -HasImplicitEnumerationConversion
,IsNumericType
그리고IsConstantNumericZero
모두가 그들이 주석에 말을 정확히 않는 내가이 변환 디렉토리에 거의 모든 코드를 작성, 나는 거기로 모두를 읽어 보시기 바랍니다. C #이 주석의 사양과 어떻게 다른지에 대한 많은 흥미로운 사실. 쉽게 찾을 수 있도록 SPEC VIOLATION으로 각각 장식했습니다.)
한 가지 더 주목할 점 : C #에서는 0 여부에 관계없이 열거 형 이니셜 라이저에서 모든 열거 형 값 을 사용할 수도 있습니다 .
enum E { A = 1 }
enum F { B = E.A } // ???
사양은 이것이 합법적이어야하는지 아닌지에 대해 다소 모호하지만, 이것은 오랫동안 컴파일러에 있었기 때문에 새로운 컴파일러가 동작을 유지할 가능성이 높습니다.
C #의 열거 형은 정의에 따른 정수 값입니다. 일관성을 위해 C #은 이러한 할당을 허용해서는 0.0
안되지만 자동으로 integer로 처리됩니다 0
. 이것은 아마도 C의 홀드 오버 일 것입니다. 여기서 리터럴 0
은 특별히 처리되었으며 정수, 부동 소수점 숫자, 널 포인터 등 주어진 유형을 본질적으로 취할 수 있습니다.
enum 은 실제로 (지원하는 모든 언어에서) 숫자 값이 아닌 의미 있고 고유 한 문자열 (레이블)로 작업하는 방법입니다. 따라서 예제에서 Foo 열거 데이터 유형을 다룰 때 Bar 및 Baz 만 사용해야 합니다. 많은 컴파일러가 정수를 사용할 수 있도록 허용하더라도 (열거 형은 일반적으로 내부적 으로 정수임) 정수 를 사용 (비교 또는 할당)해서는 안됩니다 .이 경우 0.0은 컴파일러에서 부주의하게 0으로 처리됩니다.
개념적으로, 열거 된 값에 정수 n 을 추가하거나 , n 값을 더 아래로 가져 오거나, val2 - val1 을 사용하여 얼마나 멀리 떨어져 있는지 확인하는 것이 좋습니다 . 그러나 언어 사양에서 명시 적으로 허용하지 않는 한, I 그것을 피할 것입니다. (열거 형 값을 사용할 수있는 방식에서 C 포인터와 같은 것으로 생각하십시오.) 열거 형을 부동 소수점 숫자와 그 사이에 고정 된 증분으로 구현할 수없는 이유는 없지만 들어 본 적이 없습니다. 이것은 모든 언어로 이루어집니다.
참고 URL : https://stackoverflow.com/questions/23762475/why-can-i-assign-0-0-to-enumeration-values-but-not-1-0
'IT' 카테고리의 다른 글
로컬 SQL Server 인스턴스에 대한 관리자 액세스 권한을 어떻게 부여합니까? (0) | 2020.09.11 |
---|---|
명령 줄 도구가 설치되어 있는지 확인하는 방법 (0) | 2020.09.11 |
모든 중첩 된 사전 값을 반복 하시겠습니까? (0) | 2020.09.11 |
JavaScript를 통해 사용자 로컬 LAN IP 주소를 얻을 수 있습니까? (0) | 2020.09.11 |
기능의 설명 (0) | 2020.09.11 |