차이점은 무엇이며 <out T>
그리고 <T>
? 예를 들면 다음과 같습니다.
public interface IExample<out T>
{
...
}
vs.
public interface IExample<T>
{
...
}
차이점은 무엇이며 <out T>
그리고 <T>
? 예를 들면 다음과 같습니다.
public interface IExample<out T>
{
...
}
vs.
public interface IExample<T>
{
...
}
답변:
out
제네릭 의 키워드는 인터페이스의 T 유형이 공변량임을 나타내는 데 사용됩니다. 자세한 내용은 공분산 및 반공 분산 을 참조하십시오.
고전적인 예는 IEnumerable<out T>
입니다. IEnumerable<out T>
공변량 이므로 다음을 수행 할 수 있습니다.
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
문자열이 객체에서 파생되므로 논리적으로 작동하더라도 공변량이 아닌 경우 위의 두 번째 줄은 실패합니다. 일반 인터페이스의 분산 이 C # 및 VB.NET에 추가 되기 전에 (VS 2010의 .NET 4에서) 컴파일 시간 오류였습니다.
.NET 4 이후에 IEnumerable<T>
공변량으로 표시되어되었습니다 IEnumerable<out T>
. 그 IEnumerable<out T>
안에있는 요소 만 사용하고 추가 / 변경하지 않기 때문에 열거 가능한 문자열 컬렉션을 열거 가능한 개체 컬렉션으로 취급하는 것이 안전합니다 . 즉, 공변량 을 의미합니다 .
메소드 가 IList<T>
있으므로 와 같은 유형에서는 작동하지 않습니다 . 이것이 허용된다고 가정하십시오.IList<T>
Add
IList<string> strings = new List<string>();
IList<object> objects = strings; // NOTE: Fails at compile time
그런 다음 전화를 걸 수 있습니다.
objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object
물론 이것은 실패 할 것이므로 IList<T>
공변량으로 표시 할 수 없습니다.
in
비교 인터페이스와 같은 것들에 사용되는 옵션 인 btw도 있습니다. IComparer<in T>
예를 들어 반대 방향으로 작동합니다. 인터페이스가 반 변형 이기 때문에 콘크리트를 if 의 서브 클래스 IComparer<Foo>
로 직접 사용할 수 있습니다 .IComparer<Bar>
Bar
Foo
IComparer<in T>
Image
추상 클래스 이기 때문에 ;) new List<object>() { Image.FromFile("test.jpg") };
문제없이 할 수 있거나 할 수도 new List<object>() { new Bitmap("test.jpg") };
있습니다. 당신의 문제 new Image()
는 허용되지 않는다는 것입니다 (당신도 할 수 없습니다 var img = new Image();
)
IList<object>
은 기괴한 예입니다. 원한다면 object
제네릭이 필요하지 않습니다.
사용법 in
과 out
키워드 (공분산 및 반 분산)를 쉽게 기억하기 위해 상속을 래핑으로 이미지화 할 수 있습니다.
String : Object
Bar : Foo
치다,
class Fruit {}
class Banana : Fruit {}
interface ICovariantSkinned<out T> {}
interface ISkinned<T> {}
그리고 기능,
void Peel(ISkinned<Fruit> skinned) { }
void Peel(ICovariantSkinned<Fruit> skinned) { }
받아들이는 함수 ICovariantSkinned<Fruit>
받아 들일 수있을 것이다 ICovariantSkinned<Fruit>
또는 ICovariantSkinned<Bananna>
때문에이 ICovariantSkinned<T>
공변 인터페이스와 Banana
의 유형입니다 Fruit
,
수락하는 함수는 수락 ISkinned<Fruit>
만 가능합니다 ISkinned<Fruit>
.
" out T
"는 유형 T
이 "공변량" 임을 의미합니다 . 이는 T
일반 클래스, 인터페이스 또는 메소드의 메소드에서 리턴 된 (아웃 바운드) 값으로 만 표시되도록 제한 합니다. 의미는 유형 / 인터페이스 / 방법을 수퍼 유형의과 동등한 유형으로 캐스트 할 수 있다는 것입니다 T
.
예 ICovariant<out Dog>
를 들어로 캐스팅 할 수 있습니다 ICovariant<Animal>
.
out
시행한다 T
나는이 대답을 읽기 전까지 만 반환 할 수 있습니다. 이제 전체 개념이 더 의미가 있습니다!
당신이 게시 한 링크에서 ....
일반 유형 매개 변수의 경우 out 키워드는 유형 매개 변수가 공변량임을 지정합니다 .
편집 : 다시, 당신이 게시 한 링크에서
자세한 내용은 공분산 및 공분산 (C # 및 Visual Basic)을 참조하십시오. http://msdn.microsoft.com/en-us/library/ee207183.aspx