내가 이전에 웹에이 문제를 해결 많은 정보를보고 기억합니다, 그래서 난 내 대답이 정말로 새로운 것을 추가 할지는 모르지만 나는 시도 할 것입니다.
.NET 4를 사용하는 경우 IEnumerable (Of T)의 정의가 실제로 IEnumerable (Of Out T)인지 확인하십시오. 새로운 Out 키워드는이 인터페이스의 공분산을 나타내는 버전 4에서 소개되었습니다. 그러나 List (Of T) 클래스는 단순히 List (Of T)로 정의됩니다. 여기서 Out 키워드는 사용되지 않으므로 클래스는 공 변하지 않습니다.
설명하는 것과 같은 특정 과제를 수행 할 수없는 이유를 설명하기 위해 몇 가지 예를 제공합니다. 귀하의 질문은 VB에서 작성된 것을 볼 수 있으므로 C# 사용에 대한 사과드립니다.
List<Car> cars = new List<Car>();
또한 목록을 만들 수 있습니다 : 당신은 객체가 자동차에서 파생 포함 할 수 차의 목록을 만들 수 있습니다
abstract class Vehicle
{
public abstract void Travel();
}
class Car : Vehicle
{
public override void Travel()
{
// specific implementation for Car
}
}
class Plane : Vehicle
{
public override void Travel()
{
// specific implementation for Plane
}
}
:
는 다음과 같은 클래스가 있다고 가정 평면에서 파생 된 객체 만 포함 할 수있는 평면 :
List<Plane> planes = new List<Plane>();
목록을 만들 수도 있습니다 자동차에서 파생 된 개체를 포함 할 수있는 차량의 :
List<Vehicle> vehicles = new List<Vehicle>();
그것은 자동차의 목록에 자동차를 추가하는 법, 그리고이 평면의 목록에면을 추가하는 법입니다. 또한 차량 목록에 자동차와 비행기를 모두 추가하는 것도 합법입니다.따라서, 다음 코드 줄은 모두 유효합니다
cars.Add(new Car()); // add a car to the list of cars
planes.Add(new Plane()); // add a plane to the list of planes
vehicles.Add(new Plane()); // add a plane to the list of vehicles
vehicles.Add(new Car()); // add a car to the list of vehicles
그것은 평면의 목록에 자동차를 추가하는 법률이 아니다 않으며 법적 자동차의 목록에면을 추가하는 것입니다. 코드의 다음 줄은 컴파일되지 않습니다 :
vehicles = cars; // This is not allowed
vehicles.Add(new Plane()); // because then you could do this
:
cars.Add(new Plane()); // can't add a plane to the list of cars
planes.Add(new Car()); // can't add a car to the list of planes
따라서, 자동차의 목록 또는 변수 차량에 평면의 목록을 지정하여이 제한을 우회하려고 법적 아니다
위에서 두 줄의 코드가 무엇인지 생각해보십시오. vehicles 변수는 실제로 List<Car>
객체이며 자동차에서 파생 된 객체 만 포함해야합니다. 그러나 List<Vehicle>
에 Add (Vehicle) 메서드가 포함되어 있으므로 이론적으로 Plane 개체를 List<Car>
컬렉션에 추가 할 수는 있지만 이는 정확하지 않습니다.
그러나 자동차 목록이나 비행기 목록을 IEnumerable<Vehicle>
변수에 할당하는 것은 완전히 유효합니다.
IEnumerable<Vehicle> vehicles = cars;
foreach (Vehicle vehicle in vehicles)
{
vehicle.Travel();
}
여기서 간단한 설명은 IEnumerable 인터페이스로 컬렉션을 조작 할 수 없다는 것입니다. 그것은 본질적으로 읽기 전용 인터페이스입니다. T 개체 (이 경우 Vehicle)는 IEnumerable 인터페이스의 Current 속성에서 반환 값으로 만 표시됩니다. Vehicle 객체를 입력 매개 변수로 사용하는 메서드가 없으므로 컬렉션이 불법적으로 수정 될 위험이 없습니다.
사이드 노트 : IList<T>
인터페이스가 IReadableList<out T>
인터페이스와 IWritableList<in T>
인터페이스의 합성물 인 것이 당연하다고 생각했습니다.
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/ – Oded
몇 가지 기사를 읽었으며 그 중 어떤 것도이 특정 사례에 대한 답변을 제공하지 못했습니다. 특정 유형의 목록에서 인터페이스 목록으로 직접 이동할 수있는 이유를 다루는 특정 기사 또는 그 부분을 지적 해 주시겠습니까? – Jay
http://blogs.msdn.com/b/ericlippert/archive/2007/10/26/covariance-and-contravariance-in-c-part-five-interface-variance.aspx – Oded