=============
업데이트 :이 블로그 항목의 기초 로이 답변을 사용했습니다.
ref 및 out 매개 변수가 유형 변형을 허용하지 않는 이유는 무엇입니까?
이 문제에 대한 자세한 설명은 블로그 페이지를 참조하십시오. 좋은 질문에 감사드립니다.
=============
의 당신이 수업을 가정하자 Animal
, Mammal
, Reptile
, Giraffe
, Turtle
와 Tiger
, 명백한 서브 클래스의 관계.
이제 메서드가 있다고 가정합니다 void M(ref Mammal m)
. M
읽고 쓸 수 있습니다 m
.
당신은 유형의 변수를 전달할 수 Animal
에 M
?
아니요. 해당 변수는를 포함 할 수 Turtle
있지만 M
포유류 만 포함한다고 가정합니다. A Turtle
는 Mammal
.
결론 1 : ref
매개 변수를 "더 크게"만들 수 없습니다. (포유류보다 동물이 더 많으므로 더 많은 것을 포함 할 수 있기 때문에 변수가 더 커지고 있습니다.)
당신은 유형의 변수를 전달할 수 Giraffe
에 M
?
번호 M
에 기록 할 수있는 m
, 그리고 M
된 기록 할 수 있습니다 Tiger
로를 m
. 이제 Tiger
실제로 유형 인 변수 에을 넣었습니다 Giraffe
.
결론 2 : ref
매개 변수를 "더 작게"만들 수 없습니다.
이제 고려하십시오 N(out Mammal n)
.
당신은 유형의 변수를 전달할 수 Giraffe
에 N
?
번호 N
에 쓸 수 n
및 N
를 작성 할 수 있습니다 Tiger
.
결론 3 : out
매개 변수를 "더 작게"만들 수 없습니다.
당신은 유형의 변수를 전달할 수 Animal
에 N
?
흠.
글쎄, 왜 안돼? N
에서 읽을 수없고 n
쓸 수만 있습니다. 당신은 쓰기 Tiger
유형의 변수에 Animal
모든 설정이, 맞아?
잘못된. 규칙은 " N
쓰기 만 가능 " 이 아닙니다 n
.
규칙은 간단히 다음과 같습니다.
1) 정상적으로 반환 되기 전에 N
써야 합니다. ( 드로우면 모든 베팅이 해제됩니다.)n
N
N
2)에서 N
무언가를 n
읽기 전에 무언가를 써야합니다 n
.
이는 다음과 같은 일련의 이벤트를 허용합니다.
x
유형 의 필드 를 선언하십시오 Animal
.
- 패스
x
로 out
하는 매개 변수 N
.
N
기록 Tiger
에 n
대한 별칭이다 x
.
- 다른 스레드에서 누군가가 기록
Turtle
에를 x
.
N
의 내용을 읽으려고 시도하고 유형의 변수라고 생각 n
하는 a Turtle
를 발견합니다 Mammal
.
분명히 우리는 그것을 불법으로 만들고 싶습니다.
결론 4 : out
매개 변수를 "더 크게"만들 수 없습니다.
최종 결론 : 매개 변수 도 유형이 다를 수 없습니다 . 그렇지 않으면 검증 가능한 유형 안전성을 깨는 것입니다.ref
out
기본 유형 이론의 이러한 문제에 관심이 있다면 C # 4.0에서 공분산 및 반공 변성이 작동하는 방식에 대한 시리즈를 읽어보십시오 .