转换并合并两个相同接口但不同类型的列表

时间:2017-06-16 07:34:34

标签: c# entity-framework interface casting

我有两个使用相同界面的实体。我想将从实体框架获得的结果合并到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;
}

正如你所看到的,我尝试将它们两者都用 .Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>()(抛出InvalidCastException)

这些是我的Course类,它们都实现IKurs<T1<T2>, T1>,但它们的T1和T2不同(但它们仍然使用相同的接口):

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
}

AgsTeacherToCourseXtrTeacherToCourse都实现了ITeacherToCourseAgsTeacherToCourseXtrTeacherToCourse都实现了ITeacherToCourse

如何将它们合并到一个列表中?

实际上,两个课程列表都来自不同的背景。这就是我在GetCourses()两次启动上下文的原因。

2 个答案:

答案 0 :(得分:1)

无需投射,您可以在列表中添加任何IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>

    interface IMyclass{}

    class MyType1 : IMyclass {}

    class MyType2 : IMyclass {}

    public class SomeClass
    {
        private List<IMyclass> MyList = new List<IMyclass>();

        public void DoSomething()
        {
            MyList.AddRange(new List<IMyclass> { new MyType1(), new MyType1() });
            MyList.AddRange(new List<IMyclass> { new MyType2(), new MyType2() });
        }
    }

答案 1 :(得分:1)

其中一个主要问题是

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; }
}

接口合约定义您只能设置 AdditionalTeacherDataXtrAdditionalTeacherData XtrAdditionalTeacherDataAgsAdditionalTeacherData AgsTeacherToCourse }}

当我们能够

时,我们如何确保合同
ITeacherToCourse<IAdditionalTeacherData> ttc = new XtrTeacherToCourse();
ttc.AdditionalTeacherData = new AgsAdditionalTeacherData();

如果您不想设置 AdditionalTeacherData属性,那么您可以声明界面

interface ITeacherToCourse<out T> where T : IAdditionalTeacherData
{
    int Nr { get; set; }
    T AdditionalTeacherData { get; }
}

AdditionalTeacherData现在只读Tout T

现在我们能够

ITeacherToCourse<IAdditionalTeacherData> ttc; 
ttc = new XtrTeacherToCourse();
ttc = new AgsTeacherToCourse();

这些收藏品是一样的。

总接口声明

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; }
}

和实施类

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;
}

现在我们可以添加没有任何强制转换的实例

var collection = new List<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>();

collection.Add(new XtrCourse());
collection.Add(new AgsCourse());