논리와 Collections.Generic에 대한 적용 및 상속
-
02-07-2019 - |
문제
모든 것은 객체로부터 상속됩니다.상속의 기초입니다.모든 것이 암시적으로 상속 트리에 포함될 수 있습니다.
object me = new Person();
따라서 논리적 결론에 따르면 People 그룹은 객체 그룹이기도 합니다.
List<Person> people = new List<Person>();
people.Add(me);
people.Add(you);
List<object> things = people; // Ooops.
단, 그것은 작동하지 않습니다. .NET을 설계한 사람들이 이것을 간과했거나 이유가 있는데 어느 것이 확실하지 않습니다.적어도 한 번은 이것이 유용했을 상황에 직면했지만 결국 불쾌한 해킹(캐스트 연산자를 구현하기 위해 List를 서브클래싱함)을 사용해야 했습니다.
질문은 이것입니다:이 행동에 대한 이유가 있습니까?원하는 동작을 얻는 더 간단한 솔루션이 있습니까?
기록에 따르면, 제가 이런 종류의 동작을 원했던 상황은 ToString()을 호출하고 문자열 형식을 멋지게 지정하여 개체 목록을 표시하는 일반적인 인쇄 기능이었다고 생각합니다.
다른 팁
linq를 사용하여 캐스팅할 수 있습니다.
IEnumerable<Person> oldList = someIenumarable;
IEnumerable<object> newList = oldlist.Cast<object>()
언뜻 보면 이는 직관적으로 이해되지 않습니다.하지만 그렇습니다.이 코드를 보세요:
List<Person> people = new List<Person>();
List<object> things = people; // this is not allowed
// ...
Mouse gerald = new Mouse();
things.add(gerald);
이제 우리는 갑자기 List
~의 Person
사물...와 Mouse
그 안에!
이는 유형의 객체를 할당하는 이유를 설명합니다. A<T>
유형의 변수에 A<S>
경우에도 허용되지 않습니다. S
의 슈퍼타입이다 T
.
linq 해결 방법은 좋은 방법입니다.또 다른 해결 방법은 객체 유형을 사용하고 있으므로 목록을 IEnumerable(일반 버전 아님)로 전달하는 것입니다.
편집하다:C# 4(현재 베타)는 IEnumerable에서 공변 유형 매개 변수를 지원합니다.List<object>에 직접 할당할 수는 없지만 IEnumerable<object>를 기대하는 메서드에 목록을 전달할 수 있습니다.
수행하려는 작업은 실제로 논리적으로 진행되지만 실제로는 많은 언어에서 기본적으로 지원하지 않는 기능입니다.이것은 공/반 분산(co/contra variance)이라고 불리는 것으로, 컴파일러가 객체를 암시적으로 한 사물에서 다른 사물로 암시적으로 캐스팅할 수 있는 시기와 방법과 관련이 있습니다.다행히 C# 4.0은 C# 분야에 공변성과 반공변성을 제공하며 이와 같은 암시적 캐스트가 가능해야 합니다.
이에 대한 자세한 설명을 보려면 다음 Channel9 비디오가 도움이 될 것입니다.
linq 확장 방법을 사용하면 할 수 있습니다
IEnumerable<object> things = people.Cast<object>();
List<object> things = people.Cast<object>().ToList();
그렇지 않으면 목록을 강력하게 입력하므로 암시적 변환이 허용되지 않습니다.