C # 컴파일러에서 빈 열거 형을 허용하는 이유는 무엇입니까?
오늘 실수로 값이없는 열거 형을 정의했습니다. 예를 들어 다음과 같습니다.
public enum MyConfusingEnum{}
컴파일러는 저를 정의하고 코드를 성공적으로 빌드 할 수있어서 매우 기뻤습니다.
이제는 분명히 코드 이후로 전통적인 의미에서 사용할 수 없습니다 ..
var mySadCompiler = MyConfusingEnum;
값을 지정하지만 흥미롭게도 나는하지 않습니다 이었다 ,라고 말할 수 ..
var myRoundTheHousesZeroState = Activator.CreateInstance<MyConfusingEnum>();
내가 언급했듯이 MyConfusingEnum이는 값이 0 인 값 유형입니다 .
내 질문은 컴파일러가 빈 정의를 허용하는 이유이며 유용 할 수있는 시나리오가 있습니까?
우선, 훨씬 더 쉽게 할 수있었습니다 .
MyConfusingEnum x1 = 0;
MyConfusingEnum x2 = default(MyConfusingEnum);
MyConfusingEnum x3 = new MyConfusingEnum();
MyConfusingEnum x4 = (MyConfusingEnum) 123;
위의 모든 것이 잘 작동합니다. (첫 번째가 작동한다는 사실에 놀라실 수 있습니다. 자세한 내용은 암시 적 열거 변환에 대한 사양 섹션을 참조하십시오.)
내 질문은 컴파일러가 빈 정의를 허용하는 이유입니다.
질문에 대한 답변으로 시작하겠습니다. 컴파일러도 거부하게 하시겠습니까?
class C {}
interface I {}
struct S {}
그 이유는 무엇?
당신의 질문에 더 직접적으로 대답하지 않으려면 : "왜 세상이 그것과 다르지 않습니까?" 질문은 대답하기 어렵습니다. 불가능한 질문에 대답하는 대신 "빈 열거 형을 만들면 디자인 팀에 오류가 발생했다고 가정 해 보겠습니다. 해당 프레젠테이션에 어떻게 응답 했습니까?"라는 질문에 대답하겠습니다. 그 질문은 여전히 실적 인 하지만 적어도 내가 대답 할 수있는 하나입니다.
그러면이 기능 의 비용 이 이점에 의해 정당화 되는지 여부가 문제가됩니다 .
작동하려면 언어 기능을 생각하고, 설계하고, 지정하고, 구현하고, 테스트하고, 문서화하고, 고객에게 배송해야합니다. 이것은 "오류 생성"기능이므로 오류 메시지를 문서와 마찬가지로 수십 개의 언어로 작성하고 번역해야합니다. 이 기능을 구현하는 데 5 분이 걸렸을 때 많은 돈을받는 많은 사람들이 많은 시간을 작업 할 수있었습니다.
그러나 그것은 실제로 관련 비용이 아닙니다. 기회 비용은 관련 비용이다. 예산은 한정되어 있고 기능은 무료가 아니므로 구현 된 기능은 다른 기능을 잘라야 함을 의미합니다. 이 기능을 사용하기 위해 C #의 어떤 기능을 잘라 내고 싶습니까? 손실 에서 이익을 하지 더 나은 기능을 할 수있는가이다 기회 비용 .
또한 제안한 기능은 누구에게도 명백한 이점이 없으므로 디자인위원회에 판매하기 어렵습니다. 아마도 내가 보지 못한 강력한 이점이있을 것입니다. 그렇다면 무엇입니까?
유용 할 수있는 시나리오가 있습니까?
아무도 떠오르지 않습니다. "분명히 유용하지 않은 프로그램을 거부"하는 것은 C #의 설계 목표가 아닙니다.
기본 정수 유형 ( int기본적으로 생각 )의 값을 열거 형으로 캐스팅 할 수 있으므로 (MyConfusingEnum)42이제 해당 열거 형 유형이됩니다.
일반적으로 좋은 생각이 아니라고 생각하지만 "열거 형"값이 외부 소스에서 나오고 코드가 enum.
샘플 (코드가 Enum에서 일부 "int 기반 상태"를 캡슐화한다고 가정합니다.
enum ExternalDeviceState {};
ExternalDeviceState GetState(){ ... return (ExternalDeviceState )intState;}
bool IsDeviceStillOk(ExternalDeviceState currentState) { .... }
사양은 실제로 빈 열거 형을 허용합니다.
14.1 열거 형 선언
열거 형 선언은 새로운 열거 형 유형을 선언합니다. enum 선언은 enum 키워드로 시작하여 이름, 접근성, 기본 유형 및 열거 형 멤버를 정의합니다.
enum-declaration:
attributesopt enum-modifiersopt enum identifier
enum-base(opt) enum-body ;(opt)
enum-base:
: integral-type
enum-body:
{ enum-member-declarations(opt) }
{ enum-member-declarations , }
Note that enum-member-declarations(opt) is explicitly marked as variant where nothing is inside {}.
Activator.CreateInstance<MyConfusingEnum>(); is the same as new MyConfusingEnum(). (docs)
Calling the constructor of an enum gives you 0 as value.
Because of a design decision, an enum can have any value that is valid for the backing type (usually int), it doesn't have to be a value defined in the enum.
For the reason of that design decision, I can point you to this answer on a question titled "Why does casting int to invalid enum value NOT throw exception?"
@AlexeiLevenkov has provided the spec that allows an empty enum, we can guess that the rationale for this is that since any backing type value is valid, an empty enum is allowed.
are there any scenarios where it could be useful?
As other have already mention you can assign to this enum any value that the underlying type permits by a simple cast. That way you can enforce Type Checking, in situations where an int would make thing confusing. For example:
public enum Argb : int {}
public void SetColor(Argb a) { ....
or you want to have some extension methods without clutering the int datatype, with them
public static Color GetColor(this Argb value) {
return new Color( (int)value );
}
public static void Deconstruct( this Argb color, out byte alpha, out byte red, out byte green, out byte blue ) {
alpha = (byte)( (uint)color >> 24 );
red = (byte)( (uint)color >> 16 );
green = (byte)( (uint)color >> 8 );
blue = (byte)color;
}
and use it as
var (alpha, red, green, blue) = color;
Are there any scenarios where it could be useful?
I experienced one in the Java world.
In case of enums, you know all possible values at compile time.
However, there is a time before compile time in which you may not know all values (yet) or in which you simply do not intend to implement any values, yet.
In the course of designing an API, I implemented an enumeration without any values to enable referencing it from other interfaces. I added values a later time.
참고URL : https://stackoverflow.com/questions/23794948/why-does-the-c-sharp-compiler-allow-empty-enums
'IT TIP' 카테고리의 다른 글
| 매개 변수 변경시 Angular Directive 새로 고침 (0) | 2020.10.26 |
|---|---|
| Spring Boot 및 MongoDB에 대한 연결 세부 정보를 구성하는 방법은 무엇입니까? (0) | 2020.10.26 |
| Swagger 상속 및 구성 (0) | 2020.10.26 |
| 브라우저의 ES6 : Uncaught SyntaxError : Unexpected token import (0) | 2020.10.26 |
| JavaScript에서 익명 함수에 인수를 어떻게 전달할 수 있습니까? (0) | 2020.10.26 |