C#のジェネリックの制約条件がよくわからなくなったから試してみた(敗北。打開できず)
発端
入れ子になっているコレクションクラスのinterfaceのwhereの書き方がどうすればいいのかわかなくなった。
(そもそもそーゆー実装がダメなのかもしれないけど
先に・・・
答えはない。だれか教えてほしい。
ソースの基本型
using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace ClassLibrary1 { public class VOLists { // このクラスでIVOCollections<T>を使うとする。 Listで持ちたい public List<VOList> Collections { get; set; } } public class VOList : IVOCollection<List<VO>> { public List<VO> Collection { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } public class VOObserbable : IVOCollection<ObservableCollection<VO>> { public ObservableCollection<VO> Collection { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } /// <summary>適当ValueObject</summary> public class VO { } /// <summary>VOのコレクション</summary> public interface IVOCollection<T> where T:ICollection<VO> { T Collection { get; set; } } /// <summary>VOのコレクションのコレクション</summary> public interface IVOCollections<T> // このクラスの条件どうするんじゃい。というのが本題 { T Collections { get; set; } } }
とりあえず何も制約がない場合
public class VOLists : IVOCollections<List<VOList>> { // このクラスでIVOCollections<T>を使うとする。 Listで持ちたい public List<VOList> Collections { get; set; } } /// <summary>VOのコレクションのコレクション</summary> public interface IVOCollections<T> // このクラスの条件どうするんじゃい。というのが本題 { T Collections { get; set; } }
ビルドもすんなり通ってくれる。そらそう。
エラーになるやつ1
public class VOLists : IVOCollections<List<VOList>> { // このクラスでIVOCollections<T>を使うとする。 Listで持ちたい public List<VOList> Collections { get; set; } } /// <summary>VOのコレクションのコレクション</summary> public interface IVOCollections<T> // このクラスの条件どうするんじゃい。というのが本題 where T : ICollection<IVOCollection<ICollection<VO>>> { T Collections { get; set; } }
以下のエラーになる。ICollection
重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
エラー CS0311 型 'System.Collections.Generic.List
VOListクラス側ででIVOCollection>として明示してるんだから、やってくれてもよくない?
とおもったりすんじゃがだめらしい。
整理。やりたいこと、状況
IVOCollectionは ICollection
ぶち込むことを防いでいる。
同様に
IVOCollectionsもICollection
うまくいかない。ふもも。
試しに2重に宣言するようにしてみる。
TitleVOでそうしているように、IVOCollectionを使う際の型の明示が甘いから
コンパイラーで判断できなくなっていると予想。
public class VOLists : IVOCollections<List<VOList>, List<VO>> { public List<VOList> Collections { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } /// <summary>VOのコレクションのコレクション</summary> public interface IVOCollections<T1, T2> where T1 : ICollection<T2> where T2 : IVOCollection<ICollection<VO>> { T1 Collections { get; set; } }
だめ。記載自体も冗長なので、うまくいっていてもなんか気持ち悪いので
まーそうよね。。。
なにもわかっちゃいないが・・・インターフェースでの制約をあきらめる。
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; namespace ClassLibrary1 { public class VOLists<T1, T2> : IVOCollections<T1> where T1 : List<VOList<T2>> where T2 : List<VO> { public T1 Collections { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } /// <summary>VOのコレクションのコレクション</summary> public interface IVOCollections<T> { T Collections { get; set; } } public class VOList<T> : IVOCollection<T> where T : List<VO> { public T Collection { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } public class VOObserbable : IVOCollection<ObservableCollection<VO>> { public ObservableCollection<VO> Collection { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } /// <summary>適当ValueObject</summary> public class VO { } /// <summary>VOのコレクション</summary> public interface IVOCollection<T> { T Collection { get; set; } } }
これならとおる。なにもわかっちゃいねぇ・・・うーん。なんだろう。うーん。
interfaceある意味もない気がしてきたし・・・うーん。
けつろん
よくわからん。interfaceの実装を誤解している気もするし、
そもそも設計がよくない気もする。わからん。