=============
업데이트 :
Why do ref and out parameters not allow type variation?
이 이상 블로그 페이지를 참조하십시오 :이 블로그 항목에 대한 기준으로이 답변을 사용 이 문제에 대한 논평. 좋은 질문에 감사드립니다.
=============
은의 당신이 명백한 하위 클래스 관계 클래스 Animal
, Mammal
, Reptile
, Giraffe
, Turtle
및 Tiger
을 가지고 가정하자.
이제 void M(ref Mammal m)
메서드가 있다고 가정합니다. M
은 모두 m
을 읽고 쓸 수 있습니다.
당신은 M
에 유형 Animal
의 변수를 전달할 수 있습니까?
아뇨 변수는 Turtle
포함 할 수 있지만, M
그것은 단지 포유류 포함되어 있다고 가정합니다. Turtle
은 Mammal
이 아닙니다.
결론 1 : ref
매개 변수를 "더 크게"만들 수 없습니다. (이 포유 동물보다 더 많은 동물이기 때문에 변수가 더 많은 일을 포함 할 수 있기 때문에 "더 큰"지고 있습니다.)
당신은 M
에 유형 Giraffe
의 변수를 전달할 수 있습니까?
번호 M
는 m
쓸 수 있고, M
는 Tiger
m
에 쓰기 할 수 있습니다. 이제 실제로 Giraffe
유형의 변수에 Tiger
을 넣었습니다.
결론 2 : ref
매개 변수를 "작게"만들 수 없습니다.
이제 N(out Mammal n)
을 고려하십시오.
당신은 N
에 유형 Giraffe
의 변수를 전달할 수 있습니까?
번호 N
는 n
쓸 수 있고, N
는 Tiger
를 작성 할 수 있습니다.
결론 3 : out
매개 변수를 "작게"만들 수 없습니다.
당신은 N
에 유형 Animal
의 변수를 전달할 수 있습니까?
흠.
글쎄, 왜 안 되니? N
은 n
에서 읽을 수 없습니다. 쓰기 만 가능합니다. 맞습니까? Animal
유형의 변수에 Tiger
을 쓰면 모두 설정됩니다. 맞습니까?
틀린. 규칙은 "N
은 n
에만 쓸 수 있습니다"가 아닙니다.
규칙은 간단히 다음과 같습니다
1) N
일반적으로 n
N
전에 반환에 기록한다. (N
가 발생하는 경우, 모든 베팅은 꺼져 있습니다.)
2) N
는 n
에서 뭔가를 읽기 전에 n
에 뭔가를 쓰고있다. 이벤트의 순서를 허용
는 :
- 유형
Animal
의 필드 x
를 선언합니다.
- 매개 변수를
N
으로 전달하십시오.
N
x
의 별명 인 n
에 Tiger
을 씁니다.
- 다른 스레드에서는 누군가
x
에 Turtle
을 씁니다.
N
은 n
의 내용을 읽으려고 시도하고 유형의 변수라고 생각하면 Turtle
을 찾습니다.
분명히 우리는이를 불법으로 만들고 싶습니다.
결론 4 : out
매개 변수를 "더 크게"만들 수 없습니다.
최종 결론 : 어느 ref
도 out
매개 변수가 유형에 따라 다를 수 있습니다. 그렇지 않으면 확인 가능한 유형 안전을 중단해야합니다.
기본 유형 이론의 이러한 문제에 관심이 있으시면 my series on how covariance and contravariance work in C# 4.0을 읽는 것이 좋습니다.
+1. 문제를 분명하게 보여주는 실제 수업의 예를 사용하여 훌륭한 설명을합니다 (예 : A, B, C로 설명하면 문제가 발생하지 않는 이유를 설명하기가 더 어려워집니다). –
나는이 사고 과정을 읽는 것을 겸손하게 느낀다. 나는 책으로 돌아 가야한다고 생각한다. –
이 경우, 추상 클래스 변수를 인수로 사용하지 않고 파생 클래스 객체를 전달합니다 !! –