Microsoft MVP성태의 닷넷 이야기
패턴매칭 -튜퓰비교에 관한 오류사항과 궁금증 [링크 복사], [링크+제목 복사],
조회: 7108
글쓴 사람
카짜프로그래머
홈페이지
첨부 파일
(연관된 글이 1개 있습니다.)

안녕하세요.

769P, 852P의 switch문에 에 보면

case var r when r.Equals((0,0)):

부분이 있는데요.

여기에서 Equals()안의 (0,0)은 튜플인 것으로 확인했습니다. 앞선 설명에서 튜플의 이런 형태에대한 언급은 없어 의문이 들긴 했지만 어쨌든 VS에서 확인해보니 맞네요.


 769P 에서의 경우

Action<T>의 T가 튜플인 (int,int)이기때문에 람다식에있는 arg 변수는 그와 같은 튜플이므로

r.Equals((0,0)) 은 튜플.Equals(튜플)로 같은 튜플끼리의 비교라서 문제는 없습니다

그런데 852P의 속성패턴에 앞선 예시로 다시한번 r.Equals((0,0)) 이 나오는데요.

이때는 Func<T, TResult>의 T 가 Point 타입인 관계로 람다식과 switch의 pt는 Point 타입이죠.
(별개로 VS에서 돌려보니 여기에 쓰인 pt는 아래쪽 Point 인스턴스 식별자 pt와 이름이 같으면 안된다고 해서 저는 obj라는 이름으로 바꿨습니다.)

그 결과 r.Equals((0,0)) 은 Point인스턴스.Equals(튜플) 로,
Equals가 사용자정의 타입과 튜플(정확히는 그것의 속성과 요소)을 비교하는데 쓰이게된다는데(적어도 책에서는 그러하게보임) 주목하고 의문이 꼬리에 꼬리를 물게 되었네요.

RUN해본 결과 852P에서의
case var r when r.Equals((0,0)):
부분은
Point pt = new Point { X = 0, Y = 0 };
으로 하더라도 참이 되지 않더군요.

이걸 추적하고 이해하려는 과정에서 여러가지 의문들이 생기는데 질문들이 정리는 안되고 이렇게 글로 쓰고 있습니다.


서로다른 타입의 객체를 비교하는데 오류가 나지 않았다는 것.
=> 저에게 많은 혼란을 줬는데 C#의 Equals()에대한 이해가 없어서 인 것같습니다.


Point 정의에서 ToString()을 오버라이딩 한 것
=> 이것은 현재의 코드상으로는 case문 판단에 어떠한 영향도 주고 있지않지만 굳이 오버라이딩 했기때문에 유심히 보았는데 튜플형태의 문자열로 오버라이딩 하셨더군요.
그래서

문자열.Equals(문자열)

같은 방식이 아닐까 싶기도 했습니다만
이런 ToString() 오버라이딩은 Point인스턴스 자체를 출력했을 때 (0,0)처럼 나오기는 하지만 객체상으론 문자열은 아니므로 VS에서 r은 문자열이 아닌 {(0,0)}로 나옵니다.
()안의 튜플은 (int, int) 이고요.
그래서 ToString()을 사용해서 뭘 하려했던게 아니었나 싶습니다.
하여간 저 case가 의도대로 작동하려면
r.ToString().Equals((0,0).ToString())
이라거나
855P 위치패턴처럼
switch (pt.x, pt.y)
같은식으로 되어야겠죠.
하지만 이런식으로 생각하다보면 여러가지 방법들이 나올테니 생각하기를 그만두었습니다.
원래의 의도가 무었이었는지 묻는게 빠르겠죠. 아니면 제가 생각하지 못한 뭔가가 저 예시에 있는지 알고싶습니다.


그리고 속성패턴의 사용법 설명을 위한 case이긴하겠지만, 앞서 " Point 인스턴스 값 중에서 0이 있는지 확인하는 메서드 구현"이라는 구문은
논리적으로
case var r when r.Equals((0,0)):
처럼 둘다 0,0인지 비교(AND)하는 구문은 필요없다고 느껴집니다. 어차피 pt1.x == 0 와 pt2.y == 0 만 하는 것으로도 충분하니까요
이 또한 Equals()의 기능인가? 라는 생각이 들긴했지만 그 이름과 다른곳에서의 사용에서 직감적으로 그건 아니라고 생각하게 해주는군요.


이 뒤에 속성패턴을 이해하는데 중요하거나 문제가 있는 것은 아니었으나 이로인해 많은 혼란을 주기에 뭔가 정리를 해주셨으면 합니다.



[연관 글]






[최초 등록일: ]
[최종 수정일: 12/7/2021]


비밀번호

댓글 작성자
 



2021-12-07 10시32분
결론을 먼저 말하면, 두 번째 예제가 잘못된 것입니다. (앞선 예제를 그대로 활용하다 보니 그런 오류가 포함된 것입니다.)

하나씩 정리해 드리겠습니다.

1) 769 페이지의 Tuple 사용예는 사실 앞선 "12.3 튜플" 절에서 나옵니다. 가령 749 페이지의 ParseInteger 메서드의 반환 유형에서도 (result, Number)와 같이 쓰이고 있습니다. (단순히 숫자 리터럴을 사용하지 않은 차이 정도입니다.)

2) 그리고, 852 페이지에서의 예제에서 Equals가 서로 다른 타입인데도 오류가 발생하지 않은 것은, Equals가 받아들이는 타입이 object이기 때문입니다. 그래서 Tuple 타입을 전달해도 컴파일 오류가 발생하지 않았지만, 일단 내부 구현에서는 타입이 다르므로 무조건 그런 경우에는 false를 반환하게 됩니다.

3) 예상하신대로 ToString은 단순히 보기 편한 문자열을 생산하는 용도로 정의해 둔 것입니다. (Tuple의 동작에는 어떠한 영향도 미치지 않습니다.)

4) 말씀하신대로 AND 비교는 필요 없습니다. 단지 예로 든 F#의 예제 코드에서 그것까지 포함하고 있기 때문에 예제 차원에서 그렇게 유지한 것입니다. 하지만 그리 중요하게 고수할 필요는 없으니 빼는 것이 맞다고 보고, 그럼으로써 필요 없는 혼란도 없앨 수 있겠습니다.

------------------------------------

간단한 예제 하나로 너무 많은 혼란을 주어 죄송하고, 아울러 의견 주셔서 감사합니다. 관련해서는 정오표에 추가했고,

https://www.sysnet.pe.kr/2/0/12408#errata

다음 인쇄부터는 수정해서 발행될 것입니다.
정성태

... [76]  77  78  79  80  81  82  83  84  85  86  87  88  89  90  ...
NoWriterDateCnt.TitleFile(s)
589김희택3/2/20078944리소스 추가 방법에 대한 아티클을 보던중에 질문요... [1]파일 다운로드1
588이성진2/24/200711078웹 -> 스마트클라이언트 -> 웹서비스 의 세션 공유 방법 ? [1]
583김영민2/22/20079537Vista에서 "관리자 권한으로 실행"을 통해 실행한 프로세스의 동작
584정성태2/22/200710932    답변글 [답변]: Vista에서 "관리자 권한으로 실행"을 통해 실행한 프로세스의 동작
582한귀순2/22/20079609sqlhelper 의 updatedataset
585정성태2/23/20078898    답변글 [답변]: sqlhelper 의 updatedataset [1]
579futu...2/16/200710379VS2005의 스마트 클라이언트에서 웹브라우저 예제 질문입니다. [1]
578정해봉2/16/20079608IE Embeded Assambly 방식에서 CAS 설정 방법 [1]
575박성민2/12/200710142COM에 데이터 보내기 질문입니다. [1]
571엔틱스2/7/200710818그냥... 질문은 아닙니다만... [2]
5682/6/20078242이런 오류 화면을 어떻게 찾아봐야 - 알아봐야 - 하는지요?파일 다운로드1
569정성태2/6/20079406    답변글 [답변]: 이런 오류 화면을 어떻게 찾아봐야 - 알아봐야 - 하는지요? [1]
570정성태2/6/20079536        답변글 [답변]: [답변]: 이런 오류 화면을 어떻게 찾아봐야 - 알아봐야 - 하는지요?
5732/8/20078431            답변글 [답변]: [답변]: [답변]: 이런 오류 화면을 어떻게 찾아봐야 - 알아봐야 - 하는지요? [1]파일 다운로드1
565한귀순2/5/20079062typed dataset 의 유용성
566정성태2/6/200710680    답변글 [답변]: typed dataset의 유용성 [1]
564정민영2/5/20079227혹시 이런 경우 보신적 있으신가 궁금합니다..^^; [2]
563창민이2/2/20079366Visual C++ COM Objects Returning Recordsets 사용에 대해.. [3]
562현석1/29/20079229C# 스마트응용장치에서 아이콘 움직이게하는거 질문요 ^^ [1]파일 다운로드1
559초보1/27/200710594급 질문 입니다. visual studio 자동 종료에 대한 질문입니다. [2]
558즈믄1/26/200710546.Net Framework v2.0에서 Winform의 Panel에 Excel파일 보여주기 [2]
556정재우1/26/200710293vista에서 smartclient의 System.Security.PermissionsRegistryPermission 에러 [1]
555dev....1/25/2007120172005 WebBrowser내에서 팝업 처리 문제 관련 질문입니다.
561정성태1/29/200714870    답변글 [답변]: 2005 WebBrowser 내에서 팝업 처리 문제 관련 질문입니다.
554sky1/23/200710252<급질문> interop 를 사용함에 있어 [2]
557sky1/26/20078601    답변글 [답변]: <급질문> interop 를 사용함에 있어
... [76]  77  78  79  80  81  82  83  84  85  86  87  88  89  90  ...