인터페이스 제네릭 타입 변수의 Cast 오류?

지금 제가 인터페이스 및 제네릭에 대해 이해가 부족한 듯 하여 이러한 질문을 하게 되는 것 같습니다…
여기에 쓰인 Type이나 변수명은 DB긴 한데, 실제 필요한 기능은 상관 없을 듯 하여 여기 올리게 되었습니다.

image
위 스크린샷과 같이,

분명 List<T> IList<T> 의 구현이 맞고,
MySqlParameterIDbDataParameter의 구현이 맞을텐데요.

이건 또 되니까 더 헷갈립니다.
image
이후 원래 넣으려고 했던 메서드의 인수로 넣으면 정상 작동합니다.

그런데,
image
이건 왜 안 될까요?
댓글 보고 앞에 잘린 부분 IList<IDbDataParameter>를 추가했습니다.

제가 뭔갈 놓치고 있다는 생각이 드는데, 도저히 감이 안 잡혀서 질문드립니다. ㅠㅠ

현재 버전은, VS 2019 / 2022 + ReSharper 사용중입니다.
ASP.NET 웹 프로젝트이며 제 기억이 맞다면 .Net Framework 4.0 일거에요.

2개의 좋아요
= new List<MySqlParameter>();

이 부분 뭐에다 할당하신거에요?

2개의 좋아요

System.Collections.Generic.IList<IDbDataParameter> 입니다.
아랫 줄에 메서드 인수로 같은 datatype를 요구해서 괜찮겠거니 했는데 가독성이 부족했네요.

2개의 좋아요

List 와 IList는 캐스팅이 가능한 관계지만 제네릭안에 들어가는건 같은 타입이 들어가야합니다.
그게 문법이라서 그렇게 하셔야합니다.

두번째 그림이 가능한 이유는
var로 받아서 타입을 List로 추론해주기 때문이고, 안에 있는 구성객체들은 new로 IDbDataParameter를 상속받은 실제 인스턴스를 넣어도 됩니다.

하지만 제네릭을 다른 것을 붙이는 것은 다른 문제입니다.
T가 들어가는 부분의 형이 같아야만하는 것이 제네릭문법이기 때문에 이건 상속의 관계가 아닙니다.

4개의 좋아요

맨 위 스크린샷이 MySqlParameter를 참조보기(자동 디스어셈블 된거에요.) 한거라,
보시면 상속은 정상적으로 되어 있어요.

1개의 좋아요

제가 어렴풋하게 이건 제네릭 때문에 그런것 같다 아 이게 맞는것같은데… 하는 부분을 명확히 해주셨네요,
마지막 굵게 적어주신 부분이 핵심인 듯 합니다.
문득 이런 케이스로는 그래도 허락 해주지 않을까? 하는 생각이 들었는데요,
혹시나 안되는 이유같은 케이스가 없을까요?
중첩된 제네릭을 사용할때라던가 이럴때 엉망이 될 지도 모르겠다는 짐작은 되는데…

2개의 좋아요

여기다 설명하는 하는 거보다
제네릭 타입의 공변 / 반공변 에 대해 검색해보시면 자세한 내용 확인하실 수 있을 거여욤. ~ㅂ~

3개의 좋아요

아하, 키워드 감사합니다. 새삼 잊었네요 ㅠ
그렇네요 저런 것도 문제가 되는구나…
사실 처음 답변에 보면 그게 문법입니다 가 어떻게 보면 제일 정확한듯 -0-

2개의 좋아요

참고로 List<T> 는 공변/반공변을 지원하지 않아요.
하지만 상위에 IEnumerable<T> 는 out 을 사용하기 때문에 공변이 가능합니다.

그래서

List<IDbDataParameter> param = new List<MySqlParameter>(); 

요거는 안 되지만

IEnumerable<IDbDataParameter> param = new List<MySqlParameter>();

요거는 됩니다. ㅇㅅㅇ;;

4개의 좋아요

어! 뭔가 사기당한 기분이야!
out도 있었네요;; 고맙습니다.
자꾸 머릿속 어딘가 구석탱이에 있던 지식들이 이제서야 떠오르고 있어요.

평소에 써먹을일도 없었기도 하고 제대로 짚고 넘어가지 못했나봅니다.
이번기회에 다시 복습해야겠네요.

2개의 좋아요

생각해보면 저도 이상하게
평소 같았으면 IEnumerable<T> 를 썼을 텐데
왜 하필 무슨 바람이 들어서 IList<T>를 썼었을까요?
과거의 저는 대체 무슨 생각을 했는지 원…

2개의 좋아요