Microsoft MVP성태의 닷넷 이야기
패턴매칭 -튜퓰비교에 관한 오류사항과 궁금증 [링크 복사], [링크+제목 복사],
조회: 6593
글쓴 사람
카짜프로그래머
홈페이지
첨부 파일
(연관된 글이 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

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

... 16  17  18  19  20  21  22  23  [24]  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
5319권대현4/10/20206237C++(UWP)Dll에서 C#(UWP)Dll 호출이 가능한가요? [1]
5318이승준4/9/20207108동영상 관련 업계 근황? 입니다. [1]
5317kskk...4/7/20209111OpenCV 이용 해상도 설정 질문 입니다.. [3]
5316윤현수4/7/20206345pipe 비동기방식 질문 [1]파일 다운로드1
53154/6/20207011dll파일 로드 원리? 부분에서 도움받고싶습니다. [3]
5314강성욱3/31/20208888메서드 내에서 await 2번 등장할 때의 이해 [11]파일 다운로드1
5313강성욱3/27/20206699await 2번 [1]
53121a2a...3/20/20206464Re raw data write 질문 관련 [1]파일 다운로드1
53111a2a...3/20/20207261Raw data write 관련 질문 [1]파일 다운로드1
5310아스파넬3/15/202072871초에 5회 함수호출 제한 관련 질문입니다. [1]
5309하태3/11/20209188안녕하십니까. c# Winform UI 질문드리겠습니다! [3]파일 다운로드1
5308질문3/9/20207970Window XP SP3 32bit 환경(Window Update 모두 완료)에서 .Net Framework 4.0.3 으로 빌드된 .dll 파일 gacutil.exe 등록 관련 문의 [5]
5306개발자3/9/20206840C#을 통해 인터넷 접속 가능한 이더넷을 선택할 수 있는지요? [1]
5305JaeS...3/9/20206517RAW파일 생성 질문드립니다 [8]파일 다운로드1
5303궁금하당2/27/20208823C#에서 C++ DLL읽기 (아래 글쓴이) [1]
5302궁금하당2/27/202010913C#에서 C++ DLL호출 ('PInvokeStackImbalance') [4]파일 다운로드1
5301질문합니...2/27/20206389소켓 대량 데이터 디자인 문의 [1]
5300nals...2/27/20207031vs2013에서 BinaryFormatter Serialize 후 vs2015에서 Deserialize시 예외 발생 [3]파일 다운로드1
5298질문2/26/20208402.lic 파일에 대해 질문 있습니다. [9]
5297임한승2/26/20205976vs2013에서 BinaryFormatter Serialize 후 vs2015에서 Deserialize시 예외 발생 건 [1]파일 다운로드1
5295나그네2/25/20207371클라이언트 PC 정보 조회관련.. [2]
5294닷넷초보ㅠ2/25/20207369윈폼으로 socket통신프로그램 만든후 release로 디버깅한 실행파일을 다른컴퓨터에서 실행할때 반응이없어요 [1]
5293탱코2/21/20207270검색을 하고 싶은데 어떻게 검색을 해야 할 지 모르겠습니다. [1]
5292아부리2/19/20207164XingApiNet 관련 질문 [3]
5291지현명2/15/20207910JsonConvert.Serialize 하고 Deserialize 할때 간헐적으로 한글 깨짐 현상 문의 합니다. [3]
5290베도빈2/15/20207254직접 제작한 사용자 정의 콘트롤 DLL, 실행파일에 포함시켜 배포할 수 있을까요? [1]
... 16  17  18  19  20  21  22  23  [24]  25  26  27  28  29  30  ...