최근에 나는 C#에서 매우 놀라운 동작을 발견했습니다. 나는 IEnumerable<Object>
을 매개 변수로 사용하는 메서드를 사용하고 있었고 IEnumerable<string>
을 전달했지만 불가능합니다. C#에서는이 모든 것이 왜 가능하지 않은 것보다 Object에 업 캐스트 될 수 있습니까? 완전히 혼란 스럽습니다. 누군가이 문제에 대해 저를 정리해주십시오.IEnumerable <Object>에서 IEnumerable로 캐스팅 <string>
답변
이 기술 용어는 제네릭이 C# 3.0 이하에서는 불변하다는 것입니다. C# 4.0 이후부터 캐스트가 작동합니다.
불변량이란 두 가지 제네릭 유형이 각각 매개 변수과 관련되어 있으므로 (즉, 서로의 하위 또는 상위 유형 임) 관계가 없다는 것을 의미합니다.
예를 들어 문자열이 객체의 하위 유형이기 때문에 IEnumerable<object>
과 IEnumerable<string>
사이에는 타이핑 관계가 없습니다. 그들은 문자열과 int 같은 두 개의 완전히 관련없는 유형으로 간주됩니다. (여전히 둘 다 객체의 하위 유형이지만 모두 같습니다.)
실행 한이 문제에 대한 몇 가지 해결 방법과 예외가 있습니다.
먼저 각 문자열을 객체에 캐스팅 할 수 있습니다. .NET 3.0을 사용하는 경우 Cast<T>()
확장 메소드를 사용하여이를 수행 할 수 있습니다. 그렇지 않으면 foreach를 사용하여 결과를 원하는 정적 유형의 새 변수에 넣을 수 있습니다.
둘째, 배열은 참조 유형에 대한 예외입니다. 즉, [] 유형을 객체 [] 유형을 인식하는 메소드로 전달하면 유형이 작동합니다. 당신이 다른 유형에 전달하려면
그냥 이 오래된 대답을 업데이트하면 공분산과 반공립이 C#에서 지원되며 이제는 유효한 캐스트가되었습니다. –
그런 다음 당신이 무슨 타입인지 찾기 위해 T를 조회 할 수 있습니다,
IEnumerable<T>
를 사용한다.
이것에 대해 생각하는 좋은 방법은 "이 일을 할 수 있다면 어떻게 될까요?"라고 자문하는 것입니다. 다음 예를 참조하십시오.
IEnumerable<String> strings=...;
IEnumerable<Object> objects = strings; // assume this were legal
objects.Add(new Integer(5)); // what the...
방금 문자열 목록에 정수를 추가했습니다. 컴파일러는 형식 안전성을 유지하기 위해이 작업을 수행합니다.
IEnumerable
List와 같은 Add 메소드가있는 제네릭 클래스를 대체하면 –
-1 : IEnumerable
IEnumerable<object>
을 필요로하는 기능 IEnumerable<string>
를 전달하는 가장 쉬운 방법은 다음과 같이 변환 기능을 통해 : C# 4가 나올 때 공분산 및 contravariance을 지원하기 때문에
public IEnumerable<object> convert<T>(IEnumerable<T> enumerable)
{
foreach (T o in enumerable)
yield return o;
}
,이,이 켜지지되지 않습니다.
정확하게 캐스트 <>가 다음과 같습니다. –
감사! 나는 이미이 제안에 대한 대답을 upvoted. –
다른 사람들이 지적한 것처럼 제네릭 유형은 변하지 않습니다. IEnumerable<T>
은 동일 변종이지만 C#은 현재 변종 지정을 지원하지 않습니다. C# 4.0은 향후에 지원 될 수 있도록 변형을 지원할 것으로 예상됩니다.
이제이 문제를 해결하려면 LINQ 확장 방법 Cast<object>()
을 사용할 수 있습니다. Foo
이라는 메서드가 있다고 가정하면 IEnumerable<object>>
이 필요합니다.이렇게 부를 수 있습니다.
Foo(stringEnumerable.Cast<object>());
- 1. 캐스팅 IEnumerable <Derived> to IEnumerable <BaseClass>
- 2. 어떻게 GroupedEnumerable을 IEnumerable로 캐스팅 할 수 있습니까? <T>
- 3. 캐스팅 IEnumerable <T> 목록에 <T>
- 4. IEnumerable을 IEnumerable로 변환합니다. <T>
- 5. DataRowCollection을 IEnumerable로 변환하십시오. <T>
- 6. IEnumerable <KeyValuePair <>>에서 사전 다시 만들기
- 7. C# IEnumerable <Base>을 IEnumerable로 변환 할 수 없습니다. <Derived>
- 8. 는 IEnumerable <T> 및 반사
- 9. IEnumerable <T> 목록을 바인딩 목록 <t>으로 캐스팅 할 수없는 이유는 무엇입니까?
- 10. 목록에서 선택하는 방법 <IEnumerable <ItemClass>> ~ IEnumerable <ItemClass>?
- 11. IEnumerable에서 IEnumerable <T> 가져 오기 <IEnumerable <T>>
- 12. ROWLEX는 기본적으로 IEnumerable <>을 지원합니까?
- 13. EntitySet <IEnumerable을 <T>>는 IEnumerable <T>
- 14. DataTable과 IEnumerable <T>
- 15. C# 목록 캐스팅 <>
- 16. ()가 IEnumerable <int>에서 작동하지 않는 이유는 무엇입니까?
- 17. IEnumerable <object> from IEnumrable <T>
- 18. Dictionary <>를 IEnumerable <> 소스로 채우는 것
- 19. IEnumerable <KeyValuePair>에서 일반 GetOnlyKeys에 대한 확장 메서드 <int, string>>
- 20. IEnumerable <T>을 반환하는 IEnumerable <T>에 대한 확장 메서드 정의?
- 21. 캐스팅 목록 <SomeClass> 목록에 <object>
- 22. C# 목록 캐스팅 <ushort> 목록 <short>
- 23. 캐스팅 문제 x <char> ~ x <t>
- 24. IList <T> 대 IEnumerable <T>. 보다 효율적인 IList 또는 IEnumerable <T>
- 25. 데이터 테이블을 IEnumerable <T>으로 변환하여 결과 <T> (IEnumerable <T> 데이터)로 전달합니다.
- 26. IEnumerable <T>을 어떻게 조롱합니까?
- 27. IEnumerable <T> in OCaml
- 28. IEnumerable 용 확장 메서드 <Enum>?
- 29. 익명 메서드가있는 IEnumerable <T>
- 30. null 배열과 IEnumerable <T>
어떻게 가능하지 않습니까? 그것은 ArgumentException을 던지고 있습니까? 게다가, Object로 선언 할 경우 일반 IEnumerable 사용의 요지는 무엇입니까? –
컴파일 오류 –
다음과 동일합니다 : http://stackoverflow.com/questions/6557/in-c-why-cant-a-liststring-object-be-stored-in-a-listobject-variable –