Microsoft MVP성태의 닷넷 이야기
패턴매칭 -튜퓰비교에 관한 오류사항과 궁금증 [링크 복사], [링크+제목 복사],
조회: 15223
글쓴 사람
카짜프로그래머
홈페이지
첨부 파일
(연관된 글이 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)
555dev....1/25/2007173952005 WebBrowser내에서 팝업 처리 문제 관련 질문입니다.
561정성태1/29/200720272    답변글 [답변]: 2005 WebBrowser 내에서 팝업 처리 문제 관련 질문입니다.
554sky1/23/200716033<급질문> interop 를 사용함에 있어 [2]
557sky1/26/200713459    답변글 [답변]: <급질문> interop 를 사용함에 있어
553deve...1/15/200715471오류가 나는데 도저히 모르겠네여...좀 봐주세요... [3]파일 다운로드1
551sky1/23/200714545[급질문] vb6으로 만들어진 dll 를
552정성태1/10/200716215    답변글 [답변]: [급질문] vb6으로 만들어진 dll 를 [1]
546오택성1/2/200715010스마트클라이언트 DebugIEHost.log 좀 봐 주세요. [9]
545심현철12/28/200615080ClickOnce를 이용한 SmartClient의 설치 자동화 방법에 대해서 문의를 드립니다. [1]
53912/26/200614167COM+ 자동등록 하니 속도가 영...?
540정성태12/26/200616132    답변글 [답변]: COM+ 자동등록 하니 속도가 영...? [1]
538오택성12/26/200615238스마트클라이언트에서 그리드 컴포넌트 사용시 화면에 그리드가 올라오지 않네요~ [1]
537김현12/23/200615824스마트클라이언트 CAS배포문제와, ASP.NET에서 SmartClient로 DB인자 넘기는 문제 입니다. [3]
536오택성12/23/200613377스마트 클라이언트에서 A폼에서 B폼에 있는 그리드에 데이타를 담을려고 하는데요... [2]파일 다운로드1
541달봉이12/27/200615964    답변글 [답변]: 스마트 클라이언트에서 A폼에서 B폼에 있는 그리드에 데이타를 담을려고 하는데요...
535김태곤12/22/200619912ActiveX DLL( VB 6.0 )와 관련해 질문드립니다. [1]파일 다운로드1
534심현철12/21/200615238IE Embedded SmartClient관련 질문입니다. [1]
542달봉이12/27/200615529    답변글 [답변]: IE Embedded SmartClient관련 질문입니다.
543심현철12/27/200614518        답변글 [답변]: [답변]: IE Embedded SmartClient관련 질문입니다.
544달봉이12/28/200614229            답변글 [답변]: [답변]: [답변]: IE Embedded SmartClient관련 질문입니다.
53112/20/200616014업로드 시에 로컬의 파일을 페이지 submit 시에 같이 태워보낼 수 있을 까요?
532정성태12/20/200613527    답변글 [답변]: 업로드 시에 로컬의 파일을 페이지 submit 시에 같이 태워보낼 수 있을 까요? [1]
527심현철12/19/200616355VC++과 C# COM의 interop에서 디버깅을 하는 방법에 대해서 물어봅니다.
529정성태12/19/200617564    답변글 [답변]: VC++과 C# COM의 interop에서 디버깅을 하는 방법에 대해서 물어봅니다. [1]
526독불장군12/17/200613888아랫글 과련... [1]
525독불장군12/15/200614055일주일 공부하고 있는데 잘 안되네요 도와 주세요 스마트 클라이언트파일 다운로드1
... 76  77  [78]  79  80  81  82  83  84  85  86  87  88  89  90  ...