2017-06-16 18 views
2

同じインターフェースを使用して2つのエンティティを取得しました。私は .Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>()でそれらの両方をキャストしようとした、あなたが見ることができるように同じインターフェースで異なるタイプの2つのリストをキャストしてマージする

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

(つまり、InvalidCastExceptionがスローされます)

これらは私です:私は、私はIKursの1つのリストにエンティティフレームワークから取得した結果の両方をマージしたいです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 
} 

クラスAgsTeacherToCourseXtrTeacherToCourseITeacherToCourse クラスAgsTeacherToCourseXtrTeacherToCourseを実装して、両方の私は1つのリストにそれらをマージすることができますどのようにITeacherToCourse

を実装して、両方の?実物で

、両方のコースリストは異なるコンテキストから来ます。だからこそ、私はGetCourses()の文脈を二度始めるのです。

答えて

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

あるインターフェース契約はあなただけXtrAdditionalTeacherDataAgsTeacherToCourseためAgsAdditionalTeacherData用タイプXtrAdditionalTeacherDataAdditionalTeacherData値を設定することができることを定義します。

我々は

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

、今私たちは `result.AddRange(としようとしましたすべてのキャスト

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

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

うわー。完璧。 「アウト」はまさに問題でした。サポートのためのTHX :) –

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() }); 
     } 
    } 
+0

せずにインスタンスを追加することができますのawait classes.ToListAsync()); 'しかし、これは私のコンパイラが泣くのを引き起こします:('引数型リストはssignable to parametertype IEnumerable 、IAdditionalTeacherData >> - 最初に完全な構造体をキャストする必要があると思いますか? –

+0

@MatthiasBurger何かが自分のタイプでなければなりません。あなたの複雑な型定義と混同されていることは認めなければなりませんが、このエラーフォームをコンパイルする限り、キャストは機能しません。このエラーは基本的にキャスティングが機能しないことを示しています。 – oerkelens

+0

私はまだ正確にはわからないが、Rufo卿は問題を見つけた。なぜ私はここで自分のインターフェースに「out」を使用する必要があるのか​​を調べる必要があります。しかし、あなたの助けのためのthx :) - そして、構造は混乱しています。あなたは正しい - それは私のデータベースデザインではない:D –

関連する問題