C #에서 'void'가 일반 유형으로 허용되지 않는 이유


53

void구성 할 수없고 일반적인 유형으로 허용되지 않는 것을 선호하는 디자인 결정은 무엇입니까 ? 어쨌든 그것은 단지 특별한 공허한 struct것이며 구별 Func되고 Action대의원 을 갖는 총 PITA를 피했을 것 입니다.

(C ++은 명시적인 void리턴을 허용 void하고 템플리트 매개 변수로 허용합니다 )


13
@Oded Eric Lippert가 계정을 가지고 있고 프로그래머에 참여 한다는 것을 고려할 때 , 나는 그가 방금했다고 생각합니다.
Thomas Owens

2
@ BenVoigt 단일 개인의 지식이 필요하지는 않지만 여기에 단일의 정답을 줄 수있는 사람이 있습니다 (쉽게, 가정 할 것입니다). 사양에 익숙한 사람은 특히 프로그래밍 언어 디자인에 대한 지식이있는 경우 질문에 대답 할 수 있습니다. 흥미로운 언어 디자인 / 언어 구현 질문이기도합니다.
Thomas Owens

6
@ BenVoigt : 왜 당신은 완벽하게 유효하고 흥미로운 질문을 정당한 이유없이 닫고 다른 사람이 자신의 pedantry를 만족시키기를 원하십니까? 나는 수색을했는데 답을 찾을 수 없었다. 여기 누군가가 그것에 대해 블로그 게시물을 읽었을 수도 있고, 결정을 내린 사람들이 질문에 대답하고 싶을 수도 있고, 누군가 그것에 대해 결정을 내린 사람들과 채팅을하여 스스로 질문을해서 답을 전달할 수도 있습니다. 사람들이 질문에 대답하는 것보다 질문을 닫는 데 훨씬 더 관심이 있기 때문에 나는이 사이트에 게시를 중단했습니다.

4
여기서 "큰 포인트"질문과 답변을 지적 할 수 있으며 특히 SO에 대해서는 일반적으로 "이 구문의 의미는 무엇입니까?" 모든 사람들이 const poiners에 대한 정의를 쌓아서 객체를 구성 할 수 있기 때문에 이러한 질문은 거의 끝나지 않습니다. 구타당한 트랙에 놓인 더 흥미로운 질문은 몇 가지 현명한 이유로 사이트에서 쫓겨납니다. 진지하게 데이터웨어 하우스의 몇 킬로바이트에 불과합니다. 우리는 거의 목적이 거의없는 자의적으로 해석 된 규칙을 강요하는 대신 휴식을 취하고 학습을 수용 할 수 있습니까?

2
@ThomasOwens : 나는이 사이트보다 SO에서보다 활동적입니다. 이 사이트에는 300 건에 대해 하나의 질문에 대한 답변을 게시합니다. 따라서 1500 년에 한 가지 질문에 대한 답변을 게시합니다. 답변 수 활동의 차이는 SO에 대한 C # 질문에 대답.
Eric Lippert

답변:


69

"void"의 근본적인 문제는 다른 반환 유형과 같은 의미가 아니라는 것입니다. "void"는 "이 메소드가 리턴하면 값을 전혀 리턴하지 않음"을 의미합니다. null이 아닙니다. null은 값입니다. 어떤 값도 반환하지 않습니다.

이것은 실제로 타입 시스템을 망칩니다. 유형 시스템은 본질적으로 특정 값에 어떤 연산이 유효한지 논리적으로 추론하기위한 시스템입니다. void 반환 메서드는 값을 반환하지 않으므로 "이 작업에 어떤 작업이 유효한가요?"라는 질문 전혀 이해가되지 않습니다. 작업이 유효하거나 유효하지 않은 "것"이 없습니다.

또한, 이것은 런타임에 치열한 무언가를 망칩니다. .NET 런타임은 스택 머신으로 지정된 Virtual Execution System의 구현입니다. 즉, 작업이 모두 평가 스택에 미치는 영향 측면에서 특징이있는 가상 시스템입니다. (실제로 머신은 스택과 레지스터가 모두있는 머신에서 구현되지만 가상 실행 시스템은 스택 만 가정합니다.) void 메소드 호출의 효과는 근본적으로비 공백 메소드 호출의 효과와 다릅니다. 무효가 아닌 메소드는 항상 스택에 무언가를 넣습니다. void 메소드는 스택에 무언가를 넣지 않습니다. 따라서 메소드의 리턴 값이 무시되는 경우 컴파일러는 void 및 non-void 메소드를 동일하게 처리 할 수 ​​없습니다. 메소드가 void이면 리턴 값이 없으므로 pop이 없어야합니다.

이러한 모든 이유로 "void"는 인스턴스화 할 수있는 유형이 아닙니다. 그것은 가치없습니다. 그것은 요점입니다. 객체로 변환 할 수 없으며 void 반환 메소드는 스택을 손상시키기 때문에 무효가 아닌 리턴 메소드로 다형성으로 처리 될 수 없습니다!

따라서 void는 유형 인수로 사용할 수 없으며 이는 아시다시피 수치입니다. 매우 편리합니다.

후시의 이점으로, 아무것도 반환하는 대신 아무것도 반환하지 않으면 공허 반환 방법이 자동으로 마법의 싱글 톤 참조 유형 인 "Unit"을 반환하는 것이 더 좋을 것입니다. 그런 다음 모든 메소드 호출이 스택에 무언가를 넣는 것을 알 수 있습니다. 모든 메소드 호출은 객체 유형의 변수에 할당 될 수있는 것을 반환 하며 물론 Unit은 유형 인수로 사용될 수 있음을 알고 있습니다. 별도의 Action 및 Func 델리게이트 유형이 필요하지 않습니다. 슬프게도, 그것은 우리가 속한 세상이 아닙니다.

이 정맥에 대한 더 많은 생각은 다음을 참조하십시오.


C ++은 마법의 싱글 톤 유형을 사용하지 않고도 지원합니다. 그러나 나는 그것이 완전히 다른 "일반"스타일과 C #을 사용하는 C ++과 관련이 있다고 가정합니다.
Winston Ewert

4
@WinstonEwert-C ++은 제네릭을 전혀 지원하지 않지만 기본적으로 다른 템플릿이 있습니다. 내가 이해하는 것처럼 템플릿을 사용하면 컴파일러가 전역 검색을 수행하고 유형 매개 변수로 대체하지만 제네릭을 사용하면 유형 시스템이 올바른 유형을 생성합니다. 또한 이것이 C ++ 템플릿 오류가 너무 애매한 이유라고 생각합니다. 내가 옳지 않은 말을했다면 Eric이 나를 바로 잡을 것이라고 확신합니다
Adam Rackis

1
모든 구조체는 컴파일 타임에 처리되어 스택과 인라인 된 다른 위치에 올바르게 배치되도록 생각합니다. 따라서 Void0 스택 바이트 내에서 무한한 양의 인수로 전달되도록해도 좋습니다. 구조가 object메소드를 변환 하거나 메소드를 호출 해야하는 경우 (get this) Type메모리 필드 영역 앞에 삽입 된 참조가 있는 힙에 배치하여 상자를 작성하여 (많은 CLR 구현의 경우) 올바르게 처리 할 수 ​​있습니다. 나에 관해서는 유형은 일부 특성 (필드)으로 구별 할 수있는 객체 그룹입니다. Void단지 하나의 객체입니다.
ony

1
@ OlivierJacot-Descombes : 만약 void빈 값 타입이라면, 그 문장은 기계 코드의 제로 명령으로 번역 될 것입니다. 의 하드 코딩 된 유형에는 유용하지 Void않지만 유형에 여러 일반 매개 변수가 있지만 특정 경우에는 필요하지 않은 경우에 유용합니다.
supercat

2
@EricLippert : 값 형식 반환 값을 올바르게 처리하려면 가변 개수의 단어를 스택에서 팝하는 기능이 필요합니다. 단어 수를 0으로 설정하는 데 근본적인 어려움이 있습니까? 호출자가 공간을 할당하고 참조를 전달할 책임이있는 경우 유형 시스템은 무효 참조가 의미가 없으며 아마도 노력할만한 가치가없는 것으로 인식해야하지만 "기본"문제는 보이지 않습니다. .
supercat

9

보낸 사람 : http://connect.microsoft.com/VisualStudio/feedback/details/94226/allow-void-to-be-parameter-of-generic-class-if-not-in-c-then-just-in- 실행 시간

이것은 실제로 의도적으로 설계된 것입니다-우리는 void 유형의 인스턴스를 허용하지 않습니다 (런타임의 많은 다른 유형과 함께). void 또는 void [] 인스턴스를 만들 수 없습니다. 보안을 위해 이러한 유형의 구멍을 막았습니다.

나는 내 인생에서 공허가 얼마나 안전한지 알 수는 없지만 ... 그런데.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.