2017-12-21 26 views
0

다음 코드 고려 C#에서 공통 인터페이스를 구현할 때 구현하는 인터페이스로 일반적인 캐스팅하는 방법 : 당신이 얻을모두에서 유형 매개 변수가

var abstractContainer = (IContainer<Thing>) concreteContainer; 

:이 라인에

public class Thing : IThing { } 

public interface IThing {} 

public interface IContainer<out T> where T : IThing { } 

// This works 
// public class Container<T> : IContainer<T> where T : IThing { } 

// This doesn't work 
public class Container<T> : IContainer<IThing> where T : IThing {} 

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
    var concreteContainer = new Container<Thing>(); 
    var abstractContainer = (IContainer<Thing>) concreteContainer; 
    } 
} 

을 다음 런타임 오류 : InvalidCastException: Unable to cast object of type 'CastTest.Container`1[CastTest.Thing]' to type CastTest.IContainer`1[CastTest.Thing]'.

또한 Resharper가있는 경우 Suspecious cast: there is no type in the solution which is inherited from both 'Container<Thing>' and 'IContainer<Thing>'으로 불만을 제기합니다.

둘 모두에서 상속하는 유형이 필요한 이유는 무엇입니까? Container<T>IContainer<IThing>을 구현하지 않습니까? ThingIThing을 구현하고 Container<T>T을 구현하면 IThing을 구현할 수 있으므로이 캐스트를 수행 할 수 있어야합니다.

+1

'컨테이너 '는'IContainer '이 아닌'IContainer '을 구현합니다. – Lee

+0

@hvd 뭐, 이제 너 내가 실제로주의를 기울이기를 바라는거야?! Jeez, 사람들은 많이 묻습니다. 와! –

답변

2

Doesn't Container<T> implement IContainer<IThing> ?

이 있습니다.

Since Thing implements IThing , and T in Container<T> is guaranteed to implement IThing , it seems like I should be able to do this cast.

out은 다른 방법으로 작동합니다. out은 유형이 IContainer<Thing>을 구현하면 자동으로 IContainer<IThing>을 구현한다는 것을 의미합니다. 그 반대도 마찬가지입니다.

뭔가를 반환 할 수 있기 때문에 out이라고합니다. 당신은

interface IThing<out T> { 
    T Prop { get; } 
} 

지금, IContainer<Apple> 자동 IContainer<Fruit>을 구현하는 것이 예를

을 위해해야 ​​할 수도 있습니다, 그리고 IContainer<Banana>도 자동으로 IContainer<Fruit>을 구현하는 것입니다. 이는 Apple을 반환하는 것이 Fruit을 반환하는 것으로 해석 될 수 있기 때문에 효과가 있습니다. 그러나 그것이 Fruit을 반환한다는 것을 알면 그 FruitApple인지 여부를 알 수 없습니다.

in 당신이 묻는대로 작동합니다. 당신은 IContainer<Apple> 자동 IContainer<Fruit>를 구현하지않는, 예를

이제
interface IThing<in T> { 
    void Act(T t); 
} 

을 위해있을 수 있습니다. Apple이 필요한 항목은 임의의 Fruit을 수락 할 수 없기 때문입니다. 그러나 단지 필요한 것은 Fruit입니다.은 모두 Apple입니다.

+0

감사합니다. 이것이 나의 이해를 돕기위한 열쇠였습니다. "애플이 요구하는 것은 임의의 과일을 받아 들일 수 없지만, 과일만을 필요로하는 것은 모든 사과를 받아들입니다." – watkipet