我有一个泛型类,我的所有 DAO 类都从该类派生,定义如下。我的所有实体也都有一个基类,但这不是通用的。
该方法GetIdOrSave
将与我定义的类型不同SabaAbstractDAO
,因为我试图获取主键来满足外键关系,所以这个函数要么获取主键,要么保存实体,然后获取主键钥匙。
最后一个代码片段有一个解决方案,如果我去掉通用部分,它将如何工作,所以我认为这可以通过使用方差来解决,但我不知道如何编写一个可以编译的接口。
public abstract class SabaAbstractDAO<T> :ISabaDAO<T> where T:BaseModel
{
...
public K GetIdOrSave<K>(K item, Lazy<ISabaDAO<BaseModel>> lazyitemdao)
where K : BaseModel
{
...
}
当我尝试编译时出现此错误:
Argument 2: cannot convert from 'System.Lazy<ORNL.HRD.LMS.Dao.SabaCourseDAO>' to 'System.Lazy<ORNL.HRD.LMS.Dao.SabaAbstractDAO<ORNL.HRD.LMS.Models.BaseModel>>'
我试图这样称呼它:
GetIdOrSave(input.OfferingTemplate,
new Lazy<ISabaDAO<BaseModel>>(
() =>
{
return (ISabaDAO<BaseModel>)new SabaCourseDAO() { Dao = Dao };
})
);
如果我将定义更改为此,它会起作用。
public K GetIdOrSave<K>(K item, Lazy<SabaCourseDAO> lazyitemdao) where K : BaseModel
{
那么,如何使用方差(如果需要)和泛型来编译它,这样我就可以有一个非常通用的方法,只适用于BaseModel
and AbstractDAO<BaseModel>
?我希望我只需要在方法和抽象类定义中进行更改,用法应该没问题。
更新: 有一个非常有用的回应,我有一个稍微改进的例子,但一个有趣的困境:
我现在已经定义了这个,并且我没有任何in
or out
on T这里因为我得到了矛盾的错误,如果out T
我得到它必须是contravariantly valid
并且如果in T
then covariantly valid
,所以我使它保持不变,因为它似乎 VS2010 无法计算出来。
public interface ISabaDAO<T> where T:BaseModel
{
string retrieveID(T input);
T SaveData(T input);
}
我收到此错误,尽管它确实编译了:
System.InvalidCastException: Unable to cast object of type 'ORNL.HRD.LMS.Dao.SabaCourseDAO' to type 'ORNL.HRD.LMS.Dao.ISabaDAO`1[ORNL.HRD.LMS.Models.BaseModel]'.
我修复了上面的两个代码片段,但似乎方差不会像我希望的那样起作用。
我试过这个:
public delegate K GetIdOrSave<out K>(K item, Lazy<ISabaDAO<BaseModel>> lazyitemdao)
where K : BaseModel;
但是我遇到了与界面相同的问题,如果我把out
它抱怨,那么我就提出in
了相反的抱怨。
如果这是合法的,我想我可以让它工作:
public delegate K GetIdOrSave<K>(in K item, out Lazy<ISabaDAO<BaseModel>> lazyitemdao)
where K : BaseModel;