C# 演员名单<;混凝土>;列出<;继承接口>;不带.ToList()复制操作
我在列表和IEnumerable之间的协方差/反方差方面遇到了一些问题,很可能我不完全理解这个概念。我的类必须是一个具有具体属性的具体类,以便它们可以使用ServiceStack在线序列化(SS无法正确地反序列化接口,它们的属性为空,我以前在mythz中发现一个线程,该线程表示它们不想支持IoC,并且您的DTO应该始终是具体的。如果这种态度已经改变,或者有人知道快速解决方法,那就太好了。) 关于我们的架构:C# 演员名单<;混凝土>;列出<;继承接口>;不带.ToList()复制操作,c#,list,
servicestack,ienumerable,covariance,C#,List,
servicestack,Ienumerable,Covariance,我在列表和IEnumerable之间的协方差/反方差方面遇到了一些问题,很可能我不完全理解这个概念。我的类必须是一个具有具体属性的具体类,以便它们可以使用ServiceStack在线序列化(SS无法正确地反序列化接口,它们的属性为空,我以前在mythz中发现一个线程,该线程表示它们不想支持IoC,并且您的DTO应该始终是具体的。如果这种态度已经改变,或者有人知道快速解决方法,那就太好了。) 关于我们的架构: 我们首先有EF代码,在模式项目(DLL)中有一个类似用户的实体 在接口项目(DLL)中
- 我们首先有EF代码,在模式项目(DLL)中有一个类似用户的实体
- 在接口项目(DLL)中,我们有一个
接口IUserModel
- 我们有一个
,它与用户具有相似的属性,但为了方便存储,在模型项目(DLL)中添加了更多的属性,作为域和DTO模型UserModel
- 我们在服务项目中有一个实际的ServiceStack DTO,如
,它继承了CreateUser
(为了减少服务项目中的代码量,因为它实际上与UserModel
的属性相同,但与ServiceStack路由相同,我们可以对UserModel
和CreateUser
使用相同的UpdateUser
)UserModel
//接口位于只有
//界面在里面,没有混凝土
公共接口IHaveNotesBaseModel
{
列表注释{get;set;}
}
//Concrete显式地实现接口,因此它可以
//ServiceStack序列化/反序列化的具体方法
公共类用户模型:IHaveNotesBaseModel
{
公共列表注释{get;set;}
列出IHaveNotesBaseModel.Notes
{
获取{return Notes?.ToList();}
设置{Notes=value?.Cast().ToList();}
}
}
直到今天,我们还认为这是可行的,因为在我们的工作流层中,我们试图对接口进行编程,它正在向用户添加内容。Notes
列表最终被映射下来,但我们今天发现一个场景,一个IUserModel
被传递到一个函数中,一个NoteModel
被添加到note>中es
,但如果您以后在何处调用具体的注释,则它没有该对象
我们一直在研究解决这个问题的方法,发现.ToList()
正在复制原件,这似乎是它不起作用的原因。我们需要一种方法,可以从具体界面转换到继承的界面,而无需复制列表
因此,我们知道,由于ServiceStack,我们不能做的事情有:
更改为IEnumerable
:ServiceStack不会反序列化IEnumerable,因为它是一个接口
执行强制转换(列表)注意事项
:强制转换异常
在.Cast
,(列表)Notes.Cast()之后执行强制转换:强制转换异常
试试这个
public class UserModel : IHaveNotesBaseModel
{
public List<NoteModel> Notes { get; set; }
List<INoteModel> IHaveNotesBaseModel.Notes
{
get { return Notes.Cast<INoteModel>().ToList(); }
set { Notes = value.Cast<NoteModel>().ToList(); }
}
}
公共类用户模型:IHaveNotesBaseModel
{
公共列表注释{get;set;}
列出IHaveNotesBaseModel.Notes
{
获取{return Notes.Cast().ToList();}
set{Notes=value.Cast().ToList();}
}
}
完整示例:
class Program
{
static void Main(string[] args)
{
UserModel um = new UserModel();
um.Notes = new List<NoteModel>();
um.Notes.Add(new NoteModel { MyProperty = 1 });
um.Notes.Add(new NoteModel { MyProperty = 100 });
um.Notes.Add(new NoteModel { MyProperty = 10 });
um.Notes.Add(new NoteModel { MyProperty = 10000 });
List<INoteModel> Notes = um.Notes.Cast<INoteModel>().ToList();
((IHaveNotesBaseModel)um).Notes = Notes;
}
}
// Interface is in a lower level project that only has
// interfaces in it, no concretes
public interface IHaveNotesBaseModel
{
List<INoteModel> Notes { get; set; }
}
// Concrete implements the interface explicitly so it can have
// the Concrete for ServiceStack serialization/deserialization
public class UserModel : IHaveNotesBaseModel
{
public List<NoteModel> Notes { get; set; }
List<INoteModel> IHaveNotesBaseModel.Notes
{
get { return Notes.Cast<INoteModel>().ToList(); }
set { Notes = value.Cast<NoteModel>().ToList(); }
}
}
类程序
{
静态void Main(字符串[]参数)
{
UserModel um=新的UserModel();
um.Notes=新列表();
添加(新的NoteModel{MyProperty=1});
添加(新的NoteModel{MyProperty=100});
添加(新的NoteModel{MyProperty=10});
添加(新的NoteModel{MyProperty=10000});
列表注释=um.Notes.Cast().ToList();
((IHaveNotesBaseModel)um)注释=注释;
}
}
//接口位于仅具有
//界面在里面,没有混凝土
公共接口IHaveNotesBaseModel
{
列表注释{get;set;}
}
//Concrete显式地实现接口,因此它可以
//ServiceStack序列化/反序列化的具体方法
公共类用户模型:IHaveNotesBaseModel
{
公共列表注释{get;set;}
列出IHaveNotesBaseModel.Notes
{
获取{return Notes.Cast().ToList();}
set{Notes=value.Cast().ToList();}
}
}
class Program
{
static void Main(string[] args)
{
UserModel um = new UserModel();
um.Notes = new List<NoteModel>();
um.Notes.Add(new NoteModel { MyProperty = 1 });
um.Notes.Add(new NoteModel { MyProperty = 100 });
um.Notes.Add(new NoteModel { MyProperty = 10 });
um.Notes.Add(new NoteModel { MyProperty = 10000 });
List<INoteModel> Notes = um.Notes.Cast<INoteModel>().ToList();
((IHaveNotesBaseModel)um).Notes = Notes;
}
}
// Interface is in a lower level project that only has
// interfaces in it, no concretes
public interface IHaveNotesBaseModel
{
List<INoteModel> Notes { get; set; }
}
// Concrete implements the interface explicitly so it can have
// the Concrete for ServiceStack serialization/deserialization
public class UserModel : IHaveNotesBaseModel
{
public List<NoteModel> Notes { get; set; }
List<INoteModel> IHaveNotesBaseModel.Notes
{
get { return Notes.Cast<INoteModel>().ToList(); }
set { Notes = value.Cast<NoteModel>().ToList(); }
}
}