簡體   English   中英

該類型不能在泛型類型或方法'BaseController <T>'中用作類型參數'T'。沒有隱含的參考

[英]The type cannot be used as type parameter 'T' in the generic type or method 'BaseController<T>'. There is no implicit reference

我正在嘗試創建一個通用來簡化我的代碼(它是一個web api項目),但不知何故它最終變得比我預期的更復雜。 我想要實現的是這樣的:

我的第一個想法

為了簡化我的整個實際代碼,這就是我寫的:

public interface IDatabaseTable { }

public class ReceiptIndex: IDatabaseTable { }

public interface IBackend<T> where T: IDatabaseTable { }

public class Receipts : IBackend<ReceiptIndex> { }

public class Generic<T> : SyncTwoWayXI, IBackend<T> where T:IDatabaseTable { }

public class BaseController<T> : ApiController where T: IBackend<IDatabaseTable>, new () { }

上面的所有行都在其自己的文件中單獨創建。

當我嘗試創建從BaseController繼承的控制器

public class ReceiptsBaseController : BaseController<Receipts>

我得到一個錯誤說

類型'Receipts'不能用作泛型類型或方法'BaseController'中的類型參數'T'。 沒有從“收據”到“IBackend”的隱式引用轉換。

我試圖找到一個類似的問題,並最終得到一個稱為協方差和逆變問題的東西。 任何人都可以為我正在嘗試做的事情提供反饋,或者我可以做些什么來簡化它。

解決這個問題的最簡單方法是在不使用具有一些重要意義的協方差和逆變法的情況下:

public class BaseController<TBackend, TDatabaseTable>
    : ApiController
    where TBackend : IBackend<TDatabaseTable>, new() 
    where TDatabaseTable: IDatabaseTable
{ }

並以這種方式使用它

public class ReceiptsBaseController : BaseController<Receipts, ReceiptIndex>
{
}

語法不是那么緊湊,但它的作用就像一個魅力,沒有協方差或逆變的額外含義。

您可以嘗試在IBackend中指定T 像這樣:

public class BaseController<T, TBackEndSubType> : ApiController
    where T : IBackend<TBackEndSubType>, new()
    where TBackEndSubType : IDatabaseTable { }

public class ReceiptsBaseController : BaseController<Receipts, ReceiptIndex> { }

在BaseController上你有這樣的條件:

where T: IBackend<IDatabaseTable>

但是收據中斷了IBackend <ReceiptIndex>,它與IBackend <IDatabaseTable>不直接兼容。 您可以在BaseController上添加2個通用參數:

public class BaseController<TBackend, TDatabaseTable> : ApiController 
    where TDatabaseTable: IDatabaseTable 
    where TBackend: IBackend<TDatabaseTable>, new () { }

然后你可以這樣聲明你的控制器:

public class ReceiptsBaseController : BaseController<Receipts, ReceiptIndex>

使用out修飾符: https//msdn.microsoft.com/en-us/library/dd469487.aspx

將IBackend界面更改為如下所示:

 public interface IBackend<out T> where T : IDatabaseTable { }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM