2012-06-25 2 views
3

다른 제네릭 유형 내에서 제네릭 유형을 사용하고 싶습니다.일반 유형으로 일반 유형

하지만 다음과 같은 예외를 받고 :

'MockManagers.ToPos'이 제네릭 형식 또는 메서드 'MockManagers.IMockManager<Req,Res>' 입력 매개 변수 'Res'로 사용할 수 없습니다 유형입니다. 'MockManagers.ToPos'에서 'MockManagers.MockResponseObject<System.IComparable>'까지 암시 적 참조 변환이 없습니다.

행운을 보지 않고도이 문제를 해결하기 위해 몇 가지 방법을 시도했습니다. 이 reference은 내부 generic 형식을 상위 수준 generic 형식의 매개 변수로 전달할 것을 제안합니다. 이게 유일한 해결책입니까?

코드

:
내 인터페이스 :

/// <summary> 
/// Represents IMockManager for mock object creation object. 
/// </summary> 
/// <typeparam name="Req">The request object Type.</typeparam> 
/// <typeparam name="Res">The response object type.</typeparam> 
public interface IMockManager<Req, Res> 
    where Req : MockRequestObject 
    where Res : MockResponseObject<IComparable> 
{...//interface definitions} 

객체 implementatation는 :

/// <summary> 
/// Represents Mock response for a request object 
/// </summary> 
public class ToPos : MockResponseObject<byte[]> 
{... //implementation} 

public class MockBaseObject 
{ 
    public int Id { get; set; } 
} 

public class MockResponseObject<T> : MockBaseObject 
{ 
    /// <summary> 
    /// The response content. 
    /// </summary> 
    public T Content { get; set; } 

    /// <summary> 
    /// Res creation date. 
    /// </summary> 
    public DateTime CreationDate { get; set; } 
} 
+1

'byte []'는 분명히 'IComparable'입니까? 나는 그것들의 배열이 될 것이라고 생각하지 않았을 것이다. 'Res '에 대한 제한을 제거하면 작동합니까? – Rup

+0

은 바이트 []를 제거하고 바이트 –

+0

을 사용하여 동일한 문제를가집니다. 편집 내역을 확인하십시오 - 실제로는 이해할 수 있도록 따옴표로 묶은 영역의 코드를 마크 업했습니다 (''과 같은 마크 업과 유사하므로 괄호가 숨겨 짐). 나는 다시는하지 않지만 스스로 그렇게하십시오. –

답변

3

여기서 문제는이 클래스의 일반적인 분산을 원하는 것입니다. C#은 인터페이스의 일반적인 분산 만 지원합니다. 그들은 특정 분산 제약 조건을 만족하는 경우에만 다음 그러나,

// Works fine: "string" is compatible with "IComparable" 
IComparable a = new string('a', 5); 

// Error: "List<string>" is not compatible with List<IComparable>" 
List<IComparable> b = new List<string>(); 

이 인터페이스에 대해서만 가능하며, :

다음은 작업 할 것 같다 무엇의 단순화 된 버전입니다.

// Works fine: IEnumerable is covariant 
IEnumerable<IComparable> c = new List<string>(); 

// Similarly, IEnumerable<string> is compatible with IEnumerable<IComparable>: 
IEnumerable<string> d = null; 
IEnumerable<IComparable> e = d; 

그래서 당신이 어떻게 해결합니까 : 하나는 이러한 인터페이스는 IEnumerable<out T> 인터페이스입니다? 하나의 아이디어가 있습니다.

우선 byte[]IComparable이 아니므로 사용할 수 없습니다. string을 예로 들어 보겠습니다.하지만이 인터페이스를 구현하는 데 적합한 다른 것을 찾아야 할 것입니다.

두 번째로 MockResponseObject 인터페이스를 만듭니다. 또한, T공변합니다

public interface IMockResponseObject<out T> 
{ 
    T Content { get; } 
    DateTime CreationDate { get; set; } 
} 

을 위해이 작업을 수행하려면, Content인터페이스를 통해 설정할 수 없습니다.

마지막으로,이 인터페이스를 사용하는 코드의 나머지 부분을 업데이트 :

interface IMockManager<Req, Res> 
    where Req : MockRequestObject 
    where Res : IMockResponseObject<IComparable> 
{ 
} 

public class ToPos : MockBaseObject, IMockResponseObject<string> 
{ 
    public string Content 
    { 
     get { throw new NotImplementedException(); } 
     set { throw new NotImplementedException(); } 
    } 

    public DateTime CreationDate 
    { 
     get { throw new NotImplementedException(); } 
     set { throw new NotImplementedException(); } 
    } 
} 

ToPos을 준수 여전히 세터와 Content이있다 : 당신은 오래는 인터페이스를 통해 아니므로 내용을 설정할 수 있습니다.이러한 모든 변화와

다음은 이제 유효하며 잘 컴파일 :

static IMockManager<MockRequestObject, ToPos> manager = null; 
2

당신은 단지 대신 MockResponseObject<byte[]>MockResponseObject<IComparable>에서 파생로 ToPos를 선언하지만, 다음 유형의 새 것으로 Content 속성을 숨길 수 byte[]. 그러나 이것이 작동하려면 byte[]을 랩핑하고 IComparable을 구현해야합니다. 예 :

public class ByteArrayComparable : IComparable 
{ 
    public byte[] Data { get; private set; } 
    public ByteArrayComparable(byte[] data) { Data = data; } 

    // Implement IComparable.CompareTo() method here! 
    public int CompareTo(object obj) { ... } 
} 

public class ToPos : MockResponseObject<IComparable> 
{ 
    public new byte[] Content 
    { 
     get 
     { 
      if (base.Content == null) 
       return null; 
      return ((ByteArrayComparable) base.Content).Data; 
     } 
     set 
     { 
      base.Content = value == null ? null : new ByteArrayComparable(value); 
     } 
    } 
} 
+0

답장을 보내 주셔서 감사합니다. –