Microsoft MVP성태의 닷넷 이야기
패턴매칭 -튜퓰비교에 관한 오류사항과 궁금증 [링크 복사], [링크+제목 복사]
조회: 1518
글쓴 사람
카짜프로그래머
홈페이지
첨부 파일
안녕하세요.

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

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

1  2  3  [4]  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
5630장성욱3/24/2022631로깅관련 질문입니다. [2]
5629감사합니다.3/23/2022724함수에서 예외가 발생하면 try ~ catch처리기를 찾을 때 까지 상위 함수로 계속 올라가나요? [2]
5628홍길동3/23/2022751질문드립니다. [2]파일 다운로드1
5626연준혁3/21/2022707안녕하세요. [3]
5625jaewon3/18/2022919c# 8.0 도서를 구입한 사람입니다. [1]
5624초보자3/17/2022715람다 캡처 관련 문의 [2]
5623한예지3/15/2022839인터프리터 원리가 궁금합니다. [4]
5622김민아3/8/2022912const와 readonly의 명확한 차이가 이게 맞나요? [2]
5621장성욱3/8/2022720c# 로그 관련 질문 [1]
5620김민아3/7/2022726안녕하세요 비관리 객체를 반환하는 메소드 호출 시 궁금한 점이 있어서 질문드립니다 [2]
5619팡팡이3/3/2022739RSA 문의드립니다. [3]
5618김기헌3/2/2022717안녕하세요 생성자 옆에 this 키워드를 붙여 생성자를 여러 개 호출 시 질문드립니다 [2]
5617Edun2/25/2022667ArgumentOutOrRangeException에러 발생 [2]파일 다운로드1
5616csharplearner2/24/2022698readonly struct로 선언된 구조체를 특정 클래스에서 멤버변수로 가지는 경우 [1]
5615장성욱2/22/2022983SetThreadAffinityMask를 이용한 쓰레드 지정하는 방법에 대해 궁금합니다. [4]
5614민우2/22/2022978SSL 통신 문의 [6]
5613김인태2/22/2022801서버와 PC 간의 어플리케이션 성능 차이 [1]
5612팬입니다2/20/2022668Kastrel 서버 관련 [1]
5611차가워2/19/2022724stopWatch 늘어짐 문의 [3]
5610차가워2/18/2022685Stopwatch 늘어짐 문제 [1]
5609cs린이2/15/2022808c# 함수의 호출 방식에 대해 궁금합니다! [2]
5608지호2/10/2022862시작하세요 C# 8.0 중 제네릭타입의 IEnumerable [3]파일 다운로드1
5607이로운2/10/2022731안녕하세요. 궁금한게 있어서 질문드립니다. [1]
5605강성봉2/10/2022688TCP PSH flag 패킷 수신 에러 [1]
5604LW2/9/2022753VISUAL STUDIO 2019 ==> 2020 설치시 오류가 생겨서 문의드립니다. [3]
5603김진명2/9/20221160C# 10.0 출간은 언제쯤 계획하고 계신가요? [1]
1  2  3  [4]  5  6  7  8  9  10  11  12  13  14  15  ...