投放并合并两个相同接口的列表,但不同类型 [英] Cast and merge two lists of same interfaces but different types
问题描述
IKules列表
: public async任务< IEnumerable< IKurs< ITeacherToCourse< IAdditionalTeacherData>,IAdditionalTeacherData>>>> GetCourses(bool takeXtr)
{
IEnumerable< IKurs< ITeacherToCourse< IAdditionalTeacherData> IAdditionalTeacherData>> result = new List< IKurs< ITeacherToCourse< IAdditionalTeacherData> IAdditionalTeacherData>>();
if(takeXtr)
using(var context = new Context())
{
var courses = context.XtrCourses.Include(x => x.TeachersToCourses).Where (_someCourseFilterForAgs);
result.Concat(await courses.ToListAsync())。Cast< IKurs< ITeacherToCourse< IAdditionalTeacherData> IAdditionalTeacherData>>();
}
using(var context = new Context())
{
var courses = context.AgsCourses.Include(x => x.TeachersToCourses)凡(_someCourseFilterForAgs);
result.Concat(await courses.ToListAsync())。Cast< IKurs< ITeacherToCourse< IAdditionalTeacherData> IAdditionalTeacherData>>();
}
返回结果;
}
如您所见,我尝试用
.Cast< IKurs< ITeacherToCourse< IAdditionalTeacherData>,IAdditionalTeacherData>>()
(抛出InvalidCastException)
是课程,既实现
IKurs
,但它们的T1和T2是不同的(但仍然使用相同的接口):
public class XtrCourse:Core_Xtr_Course,IKurs< XtrTeacherToCourse,XtrAdditionalTeacherData>
{
public int Nr {get;组;
// property
public ICollection< XtrTeacherToCourse> TeachersToCourses {get;组; }
}
public class AgsCourse:Core_Ags_Course,IKurs< AgsTeacherToCourse,AgsAdditionalTeacherData>
{
public int Nr {get;组; }
//属性
public ICollection< AgsTeacherToCourse> TeachersToCourses {get;组; }
}
public interface IKurs< TTeacherToCourse,TAdditionalTeacherData>
其中TTeacherToCourse:ITeacherToCourse< TAdditionalTeacherData>
其中TAdditionalTeacherData:IAdditionalTeacherData
{
int Nr {get;组; }
ICollection< TTeacherToCourse> TeachersToCourses {get;组; }
}
public interface ITeacherToCourse< T>其中T:IAdditionalTeacherData
{
int Nr {get;组; }
T AdditionalTeacherData {get;组; }
}
public interface IAdditionalTeacherData
{
//属性
}
class AgsTeacherToCourse
和 XtrTeacherToCourse
都实现 ITeacherToCourse
class AgsTeacherToCourse
和 XtrTeacherToCourse
都实现 ITeacherToCourse
如何将它们合并到一个列表?
,两个课程列表来自不同的上下文。这就是为什么我在 GetCourses()
中启动上下文。
p>主要问题之一是
界面ITeacherToCourse< T>其中T:IAdditionalTeacherData
{
int Nr {get;组; }
T AdditionalTeacherData {get;组; }
}
class XtrTeacherToCourse:ITeacherToCourse< XtrAdditionalTeacherData>
{
public int Nr {get;组; }
public XtrAdditionalTeacherData AdditionalTeacherData {get;组; }
}
class AgsTeacherToCourse:ITeacherToCourse< AgsAdditionalTeacherData>
{
public int Nr {get;组; }
public AgsAdditionalTeacherData AdditionalTeacherData {get;组; }
}
界面契约定义您只能设置 的值
AdditionalTeacherData
类型 XtrAdditionalTeacherData
for XtrAdditionalTeacherData
和 AgsAdditionalTeacherData
for AgsTeacherToCourse
。
我们如何确保当我们能够
ITeacherToCourse< IAdditionalTeacherData> ttc = new XtrTeacherToCourse();
ttc.AdditionalTeacherData = new AgsAdditionalTeacherData();
如果您不想设置 AdditionalTeacherData
属性,则可以声明接口,如
interface ITeacherToCourse< out T>其中T:IAdditionalTeacherData
{
int Nr {get;组; }
T AdditionalTeacherData {get; }
}
AdditionalTeacherData
现在只读和 T
是一个 out T
。
现在我们可以
ITeacherToCourse< IAdditionalTeacherData> TTC;
ttc = new XtrTeacherToCourse();
ttc = new AgsTeacherToCourse();
与集合相同。
总界面声明
界面IAdditionalTeacherData
{
}
接口ITeacherToCourse< out T>其中T:IAdditionalTeacherData
{
int Nr {get;组; }
T AdditionalTeacherData {get; }
}
接口IKurs< out TTeacherToCourse,out TAdditionalTeacherData>
其中TTeacherToCourse:ITeacherToCourse< TAdditionalTeacherData>
其中TAdditionalTeacherData:IAdditionalTeacherData
{
int Nr {get;组; }
IEnumerable< TTeacherToCourse> TeachersToCourses {get; }
}
和实施类
class XtrAdditionalTeacherData:IAdditionalTeacherData
{
}
class XtrTeacherToCourse:ITeacherToCourse< XtrAdditionalTeacherData>
{
public int Nr {get;组; }
public XtrAdditionalTeacherData AdditionalTeacherData {get;组; }
}
class XtrCourse:IKurs< XtrTeacherToCourse,XtrAdditionalTeacherData>
{
public int Nr {get;组; }
public ICollection< XtrTeacherToCourse> TeachersToCourses {get;组; }
//显式实现
IEnumerable< XtrTeacherToCourse> IKurs< XtrTeacherToCourse,XtrAdditionalTeacherData> .TeachersToCourses => TeachersToCourses;
}
class AgsAdditionalTeacherData:IAdditionalTeacherData
{
}
class AgsTeacherToCourse:ITeacherToCourse< AgsAdditionalTeacherData>
{
public int Nr {get;组; }
public AgsAdditionalTeacherData AdditionalTeacherData {get;组; }
}
class AgsCourse:IKurs< AgsTeacherToCourse,AgsAdditionalTeacherData>
{
public int Nr {get;组; }
public ICollection< AgsTeacherToCourse> TeachersToCourses {get;组; }
//显式执行
IEnumerable< AgsTeacherToCourse> IKurs< AgsTeacherToCourse,AgsAdditionalTeacherData> .TeachersToCourses => TeachersToCourses;
}
现在我们可以添加没有任何演员的实例
var collection = new List< IKurs< ITeacherToCourse< IAdditionalTeacherData> IAdditionalTeacherData>>();
collection.Add(new XtrCourse());
collection.Add(new AgsCourse());
I got two entities with using same interface. I want to merge both results I get from entity framework to one list of IKurs
:
public async Task<IEnumerable<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>> GetCourses(bool takeXtr)
{
IEnumerable<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>> result = new List<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>();
if (takeXtr)
using (var context = new Context())
{
var courses = context.XtrCourses.Include(x=>x.TeachersToCourses).Where(_someCourseFilterForAgs);
result.Concat(await courses.ToListAsync()).Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>();
}
using (var context = new Context())
{
var courses = context.AgsCourses.Include(x=>x.TeachersToCourses).Where(_someCourseFilterForAgs);
result.Concat(await courses.ToListAsync()).Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>();
}
return result;
}
As you can see, I tried casting them both with
.Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>()
(that throws an InvalidCastException)
These are my Course
classes, both implementing IKurs<T1<T2>, T1>
but their T1 and T2 are different (but still they use the same interfaces):
public class XtrCourse : Core_Xtr_Course, IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData>
{
public int Nr { get; set; }
// properties
public ICollection<XtrTeacherToCourse> TeachersToCourses { get; set; }
}
public class AgsCourse : Core_Ags_Course, IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData>
{
public int Nr { get; set; }
// properties
public ICollection<AgsTeacherToCourse> TeachersToCourses { get; set; }
}
public interface IKurs<TTeacherToCourse, TAdditionalTeacherData>
where TTeacherToCourse : ITeacherToCourse<TAdditionalTeacherData>
where TAdditionalTeacherData: IAdditionalTeacherData
{
int Nr { get; set; }
ICollection<TTeacherToCourse> TeachersToCourses { get; set; }
}
public interface ITeacherToCourse<T> where T : IAdditionalTeacherData
{
int Nr { get; set; }
T AdditionalTeacherData { get; set; }
}
public interface IAdditionalTeacherData
{
// properties
}
classes AgsTeacherToCourse
and XtrTeacherToCourse
both implement ITeacherToCourse
classes AgsTeacherToCourse
and XtrTeacherToCourse
both implement ITeacherToCourse
How can I merge them to one list?
In real, both course-lists come from different contexts. That's why I'm initiating the context in GetCourses()
twice.
One of the main problems is
interface ITeacherToCourse<T> where T : IAdditionalTeacherData
{
int Nr { get; set; }
T AdditionalTeacherData { get; set; }
}
class XtrTeacherToCourse : ITeacherToCourse<XtrAdditionalTeacherData>
{
public int Nr { get; set; }
public XtrAdditionalTeacherData AdditionalTeacherData { get; set; }
}
class AgsTeacherToCourse : ITeacherToCourse<AgsAdditionalTeacherData>
{
public int Nr { get; set; }
public AgsAdditionalTeacherData AdditionalTeacherData { get; set; }
}
The interface contract defines that you can only set a value to AdditionalTeacherData
of type XtrAdditionalTeacherData
for XtrAdditionalTeacherData
and AgsAdditionalTeacherData
for AgsTeacherToCourse
.
How can we ensure this contract when we were able to
ITeacherToCourse<IAdditionalTeacherData> ttc = new XtrTeacherToCourse();
ttc.AdditionalTeacherData = new AgsAdditionalTeacherData();
If you do not want to set the AdditionalTeacherData
property then you can declare the interface like
interface ITeacherToCourse<out T> where T : IAdditionalTeacherData
{
int Nr { get; set; }
T AdditionalTeacherData { get; }
}
AdditionalTeacherData
is now readonly and T
is an out T
.
Now we are able to
ITeacherToCourse<IAdditionalTeacherData> ttc;
ttc = new XtrTeacherToCourse();
ttc = new AgsTeacherToCourse();
With the collections it is the same.
The total interface declaration
interface IAdditionalTeacherData
{
}
interface ITeacherToCourse<out T> where T : IAdditionalTeacherData
{
int Nr { get; set; }
T AdditionalTeacherData { get; }
}
interface IKurs<out TTeacherToCourse, out TAdditionalTeacherData>
where TTeacherToCourse : ITeacherToCourse<TAdditionalTeacherData>
where TAdditionalTeacherData : IAdditionalTeacherData
{
int Nr { get; set; }
IEnumerable<TTeacherToCourse> TeachersToCourses { get; }
}
and the implementing classes
class XtrAdditionalTeacherData : IAdditionalTeacherData
{
}
class XtrTeacherToCourse : ITeacherToCourse<XtrAdditionalTeacherData>
{
public int Nr { get; set; }
public XtrAdditionalTeacherData AdditionalTeacherData { get; set; }
}
class XtrCourse : IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData>
{
public int Nr { get; set; }
public ICollection<XtrTeacherToCourse> TeachersToCourses { get; set; }
// explicit implementation
IEnumerable<XtrTeacherToCourse> IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData>.TeachersToCourses => TeachersToCourses;
}
class AgsAdditionalTeacherData : IAdditionalTeacherData
{
}
class AgsTeacherToCourse : ITeacherToCourse<AgsAdditionalTeacherData>
{
public int Nr { get; set; }
public AgsAdditionalTeacherData AdditionalTeacherData { get; set; }
}
class AgsCourse : IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData>
{
public int Nr { get; set; }
public ICollection<AgsTeacherToCourse> TeachersToCourses { get; set; }
// explicit implementation
IEnumerable<AgsTeacherToCourse> IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData>.TeachersToCourses => TeachersToCourses;
}
and now we can add the instances without any cast
var collection = new List<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>();
collection.Add(new XtrCourse());
collection.Add(new AgsCourse());
这篇关于投放并合并两个相同接口的列表,但不同类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!