=============
업데이트 :이 블로그 항목의 기초 로이 답변을 사용했습니다.
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써야 합니다. ( 드로우면 모든 베팅이 해제됩니다.)nNN
2)에서 N무언가를 n읽기 전에 무언가를 써야합니다 n.
이는 다음과 같은 일련의 이벤트를 허용합니다.
x유형 의 필드 를 선언하십시오 Animal.
- 패스
x로 out하는 매개 변수 N.
N기록 Tiger에 n대한 별칭이다 x.
- 다른 스레드에서 누군가가 기록
Turtle에를 x.
N의 내용을 읽으려고 시도하고 유형의 변수라고 생각 n하는 a Turtle를 발견합니다 Mammal.
분명히 우리는 그것을 불법으로 만들고 싶습니다.
결론 4 : out매개 변수를 "더 크게"만들 수 없습니다.
최종 결론 : 매개 변수 도 유형이 다를 수 없습니다 . 그렇지 않으면 검증 가능한 유형 안전성을 깨는 것입니다.refout
기본 유형 이론의 이러한 문제에 관심이 있다면 C # 4.0에서 공분산 및 반공 변성이 작동하는 방식에 대한 시리즈를 읽어보십시오 .