문제

최근에 나는 C#에서 매우 놀라운 동작을 발견했습니다. 나는 취하는 방법이 있었다 IEnumerable<Object> 매개 변수로서 나는 통과했다IEnumerable<string> 그러나 불가능합니다. C#에서는 이것이 불가능한 이유보다 모든 것이 객체로 향상 될 수 있습니까? 나에게 완전히 혼란 스러워요. 이 문제에 대해 누군가 나를 정리 해주세요.

도움이 되었습니까?

해결책

이에 대한 기술 용어는 제네릭이 C# 3.0 이상에서 변하지 않는다는 것입니다. C#4.0부터 캐스트가 작동합니다.

불변의 의미는 일반적인 유형이기 때문에 두 가지 일반 유형 사이에 관계가 없다는 것입니다. 매개 변수 관련이 있습니다 (즉, 서로의 하위 또는 초대형).

예에서는 IEnumerable<object> 그리고 IEnumerable<string>, 문자열은 객체의 하위 유형이기 때문입니다. 그들은 문자열과 int와 같은 완전히 관련이없는 두 가지 유형으로 간주됩니다 (여전히 둘 다 객체의 하위 유형이지만 모든 것이 있습니다).

이 문제에 대한 몇 가지 해결 방법과 예외가 있습니다.

먼저 각 문자열을 개별적으로 객체에 캐스트 할 수 있습니다. .NET 3.0을 사용하는 경우 Cast<T>() 확장 방법. 그렇지 않으면 Foreach를 사용하여 결과를 원하는 정적 유형의 새로운 변수에 넣을 수 있습니다.

둘째, 배열은 참조 유형에 대한 예외이며, 즉 문자열 [] 유형을 통과하는 객체 [] 유형을 설명하는 메소드로 전달됩니다.

다른 팁

다른 사람들이 지적했듯이 제네릭 유형은 변하지 않습니다. IEnumerable<T> 공동 변수 일 수 있지만 C#은 현재 변형 지정을 지원하지 않습니다. C# 4.0은 변형을 지원할 것으로 예상되므로 향후 지원 될 수 있습니다.

지금이 문제를 해결하려면 LINQ 확장 방법을 사용할 수 있습니다. Cast<object>(). 당신이라는 메소드가 있다고 가정합니다 Foo 그것은 필요합니다 IEnumerable<object>>. 당신은 이것을 이렇게 부를 수 있습니다.

Foo(stringEnumerable.Cast<object>());

가장 쉬운 방법 IEnumerable<string> 기능을 요구합니다 IEnumerable<object> 다음과 같은 기능을 변환하는 것입니다.

public IEnumerable<object> convert<T>(IEnumerable<T> enumerable)
    {
    foreach (T o in enumerable)
        yield return o;
    }

C# 4가 나오면 공분산과 비밀화를 지원하기 때문에 이것은 악의적이지 않습니다.

당신은 사용해야합니다

IEnumerable<T> 

다른 유형으로 전달하려면 T를 쿼리하여 어떤 유형인지 확인할 수 있습니다.

이것에 대해 생각하는 좋은 방법은 "이것을 할 수 있다면 어떻게 될까요?"라고 스스로에게 물어 보는 것입니다. 다음 예를 들어보세요 :

IEnumerable<String> strings=...;
IEnumerable<Object> objects = strings; // assume this were legal

objects.Add(new Integer(5)); // what the...

우리는 방금 문자열 목록에 정수를 추가했습니다. 컴파일러는 유형 안전을 보존하기 위해이를 수행합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top