2011-12-30 8 views
8

已經踩上了我自己的腳趾,我認爲這是一段非常簡單的代碼。代碼比文字說得更好,所以就是這樣。C#接口和通用組合。想要返回<T>而不是其基本接口

public interface IResponse 
{ 
    IResult Result { get; set; } 
} 

public class Response<T> : IResponse 
    where T : IResult 
{ 
    public T Result { get; set; } 
    // COMPILER ERROR: Property 'Result' cannot be implemented property from interface 'IResponse'. Type should be 'IResult'. 
} 

編譯器不允許我這樣做,因爲IResponse要求結果爲IResult,但是我想利用仿製藥的優勢,在實現類和強類型的結果T.這是不可能的,還是我錯過了一些微不足道的東西?

回答

11

他們你必須做出IResponse通用太:

public interface IResponse<T> 
    where T : IResult 
{ 
    T Result { get; set; } 
} 

public class Response<T> : IResponse<T> 
    where T : IResult 
{ 
    public T Result { get; set; } 
} 

如果你想保持IResponse接口,而在圓通泛型參數,你可以去更炫。以下有兩個接口,其中類透明也實現了接口,而通用的參數:

public interface IResponse 
{ 
    IResult Result { get; set; } 
} 

public interface IResponse<T> : IResponse 
    where T : IResult 
{ 
    T Result { get; set; } 
} 

public class Response<T> : IResponse<T> 
    where T : IResult 
{ 
    public T Result { get; set; } 

    IResult IResponse.Result 
    { 
     get { return Result; } 
     set { Result = (T)value; } 
    } 
} 

而且,如果你想更貼近你原來的實現,可以去掉的IResponse<T>並獲得以下:

public interface IResponse 
{ 
    IResult Result { get; set; } 
} 

public class Response<T> : IResponse 
    where T : IResult 
{ 
    public T Result { get; set; } 

    IResult IResponse.Result 
    { 
     get { return Result; } 
     set { Result = (T)value; } 
    } 
} 
+0

問題與使得界面也一般是我用它在另一個類,我不希望它迫使我指定T. – Arkiliknam 2011-12-30 10:44:31

+0

是的,我想到這一點。這就是爲什麼我剛添加第二個和第三個選項。 – 2011-12-30 10:45:28

+0

剛剛看到你的更新。看起來不錯,什麼東西埋在我的頭上。好東西! :) – Arkiliknam 2011-12-30 10:46:15

1

您應該在IResponse中將IResponse泛型和Result類型的結果作爲類型參數傳遞給此接口。

public interface IResponse<T> where T : IResult 
{ 
    T Result { get; set; } 
} 

public class Response<T> : IResponse<T> 
{ 
    public T Result { get; set; } 
} 
4

如果你「只是」想「利用仿製藥的」你不需要IResponse

界面正在解決另一個問題,一個與您的願望不兼容的問題。考慮

IResponse r = x ? new Response<int>() : new Response<string>(); 
r.Result = ... // what type? 

因此,要麼讓IResponse通用太或乾脆刪除它。

1
public interface IResponse<T> where T : IResult 
{ 
    T Result { get; set; } 
} 

public class Response<T> : IResponse<T> where T : IResult 
{ 
    public T Result { get; set; } 
    // NO MORE COMPILER ERROR 
} 
2

試試這個

public class Response<T> : IResponse 
    where T : IResult 
{ 
    public T Result { get; set; } 
    // COMPILER ERROR: Property 'Result' cannot be implemented property from interface 'IResponse'. Type should be 'IResult'. 

    IResult IResponse.Result 
    { 
     get { return this.Result; } 
     set { this.Result = (T)value; } 
    } 
}