[英]The type cannot be used as type parameter 'T' in the generic type or method 'BaseController<T>'. There is no implicit reference
I'm trying to create a generic to simplify my codes (it's a web api project), but at somehow it's ended up becoming more complicated than I expected. 我正在尝试创建一个通用来简化我的代码(它是一个web api项目),但不知何故它最终变得比我预期的更复杂。 What I'm trying to implement is something like this:
我想要实现的是这样的:
To simplify my whole real code, this is what I've written: 为了简化我的整个实际代码,这就是我写的:
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 () { }
All of the line above created separately in its own file. 上面的所有行都在其自己的文件中单独创建。
When I try to create controller that Inherit from BaseController 当我尝试创建从BaseController继承的控制器
public class ReceiptsBaseController : BaseController<Receipts>
I get an error said 我得到一个错误说
The type 'Receipts' cannot be used as type parameter 'T' in the generic type or method 'BaseController'.
类型'Receipts'不能用作泛型类型或方法'BaseController'中的类型参数'T'。 There is no implicit reference conversion from 'Receipts' to 'IBackend'.
没有从“收据”到“IBackend”的隐式引用转换。
I try to find a similar problem and end up with something called Covariance and Contravariance problem. 我试图找到一个类似的问题,并最终得到一个称为协方差和逆变问题的东西。 Can anyone give feedback for what I'm trying to do or maybe something that can I do to simplify it.
任何人都可以为我正在尝试做的事情提供反馈,或者我可以做些什么来简化它。
The easiest way to solve this, without using covariance and contravariance, which has some important implications, is this: 解决这个问题的最简单方法是在不使用具有一些重要意义的协方差和逆变法的情况下:
public class BaseController<TBackend, TDatabaseTable>
: ApiController
where TBackend : IBackend<TDatabaseTable>, new()
where TDatabaseTable: IDatabaseTable
{ }
And use it in this way 并以这种方式使用它
public class ReceiptsBaseController : BaseController<Receipts, ReceiptIndex>
{
}
The syntax is not so compact, but it works like a charm, without the extra implications of covariance or contravariance. 语法不是那么紧凑,但它的作用就像一个魅力,没有协方差或逆变的额外含义。
You can try to specify the T
in IBackend. 您可以尝试在IBackend中指定
T
Like this: 像这样:
public class BaseController<T, TBackEndSubType> : ApiController
where T : IBackend<TBackEndSubType>, new()
where TBackEndSubType : IDatabaseTable { }
public class ReceiptsBaseController : BaseController<Receipts, ReceiptIndex> { }
On the BaseController you have this condition: 在BaseController上你有这样的条件:
where T: IBackend<IDatabaseTable>
but receipts inhertits IBackend<ReceiptIndex>, which is not directly compatible with IBackend<IDatabaseTable>. 但是收据中断了IBackend <ReceiptIndex>,它与IBackend <IDatabaseTable>不直接兼容。 You could add 2 generic parameters on your BaseController:
您可以在BaseController上添加2个通用参数:
public class BaseController<TBackend, TDatabaseTable> : ApiController
where TDatabaseTable: IDatabaseTable
where TBackend: IBackend<TDatabaseTable>, new () { }
then you can declare your controller like this: 然后你可以这样声明你的控制器:
public class ReceiptsBaseController : BaseController<Receipts, ReceiptIndex>
using the out modifier: https://msdn.microsoft.com/en-us/library/dd469487.aspx 使用out修饰符: https : //msdn.microsoft.com/en-us/library/dd469487.aspx
Change the IBackend interface to look like this: 将IBackend界面更改为如下所示:
public interface IBackend<out T> where T : IDatabaseTable { }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.