2017-09-11 5 views
0
// T => a class 
// I => Guid, int etc.. 

public interface IBaseX<T, I> 
     where T : BaseY<I> {..} 
public class BaseX<T, I> : IBaseX<T, I> 
     where T : BaseY<I> {..} 

// it works but, 

public interface IMyClass<T, I> 
     where T : IBaseX<T, I> {..} 
public class MyClass<T, I> 
     where T : BaseX<T, I>, IMyClass<T, I> 

// this not works, why not? 

エラー: 型Tがジェネリック型またはメソッドIBaseXで型パラメータTとして使用することはできません。は、2種類のインタフェースを継承し<T, I>

私のORMプロジェクトは、含まれてい:


は、いくつかの問題があり、イム書き込みが更新TからBaseY

へのボクシング変換やタイプパラメータ変換はありません、プロジェクトのルートに

: BaseEntity.cs:

public abstract class BaseEntity<T> 
{ 
    public T ID { get; set; } 
    ..... 
} 

コンテンツフォルダ: Page.cs:

public class Page : BaseEntity<int> 
{ 
    [MaxLength(250)] 
    [Required] 
    public string Title { get; set; } 
    .... 
} 

PageComment.cs:私はdatalayerプロジェクトを持っている

public class PageComment : BaseEntity<int> 
{ 
    public int PageID { get; set; } 

    [Required] 
    [MaxLength(500)] 
    public string Body { get; set; } 

    [Required] 
    [MaxLength(175)] 
    public string Email { get; set; } 

    [Required] 
    [MaxLength(150)] 
    public string Title { get; set; } 
    .... 
} 

、含まれています

ベースフォルダ:

IBaseDAL.cs:

public interface IBaseDAL<T, I> where T : BaseEntity<I> 
{ 
    void Save(T e, string who, WebsiteContext ctx = null); 
    void Update(T e, string who, WebsiteContext ctx = null); 
    void Delete(T e, string who, WebsiteContext ctx = null); 

} 

BaseDAL.cs :

public class BaseDAL<T, I> : IBaseDAL<T, I> where T : BaseEntity<I> 
{ 
    public void Save(T e, string who, WebsiteContext ctx = null) { ... } 
} 

コメントフォルダ:

ICommentDAL.cs:

public interface ICommentDAL<T> where T : BaseEntity<int>, IBaseDAL<T, int> 
{ 
    int Save(WebsiteContext ctx, NewCommentDTO nc, string who); 
    .... 
} 

CommentDAL.cs:

public class CommentDAL<T> 
    where T : BaseEntity<int>, IBaseDAL<T, int>, ICommentDAL<T> 
{ 
    BaseDAL<T, int> baseDAL = new BaseDAL<T, int>(); 

    public int Save(WebsiteContext ctx, NewCommentDTO<T> nc, string who) 
    { 
     ORM.Content.PageComment pc = new PageComment() 
     { 
      Body = nc.Body, 
      ... 
     }; 
     baseDAL.Save(pc as T, who, ctx); 
    } 
} 

ORM.Content.PageCommentクラスはT

として使用する必要がありますが、私が「T.」と書くと、BaseEntityフィールドに来る..

serviceLayerで、私はcommentDAL.Saveメソッドを呼び出します:

_commentDAL.Save(...);

どのように私は値commentDAL.SaveでTクラスを(渡すことができます)

+1

をので、あなたは 'が' 'Tたい:BaseX {..}' ''や '' 'T:BaseY は{..}' ''? – tym32167

+0

ベースXのTはベースYである必要があります –

+1

ジェネリックタイプの制約の「継承」はありません。ベースタイプまたはインターフェイスで必要な制約を明示的に含める必要があります。 –

答えて

0

は、以下の回答を参照してください、しかし、あなたはおそらく、あなたの意図したタイプのデザインについての詳細を教えてくださいますのでご注意ください。なぜなら、いくつかのジェネリックをコンパイラで動作させるだけでは、おそらくあなたが実際に望むコードが得られないからです。

次作品:

public class BaseY<T> 
{ 

} 
public interface IBaseX<T, I> 
     where T : BaseY<I> 
{ 
} 
public class BaseX<T, I> : IBaseX<T, I> 
     where T : BaseY<I> 
{ 
} 

// it works but, 

public interface IMyClass<T, I> 
     where T : BaseY<I>, IBaseX<T, I> 
{ 
} 
public class MyClass<T, I> 
     where T : BaseY<I>, IBaseX<T, I>, IMyClass<T, I> 
{ 
} 

(注)where T : BaseY<I>, BaseX<T, I>, IMyClass<T, I>を言うことができないので、あなたは、T〜2クラスを制約することはできません。代わりに、構成が意味をなさなくするためには、BaseXBaseYは継承階層にある必要があり、より派生したクラスの制約を書くことができます。あなたの更新構造を考慮


、私は次のように変更すべきだと思う:

// from 
public interface ICommentDAL<T> where T : BaseEntity<int>, IBaseDAL<T, int> 
// to 
public interface ICommentDAL<T> : IBaseDAL<T, int> 
    where T : BaseEntity<int> 
// or to 
public interface ICommentDAL : IBaseDAL<PageComment, int> 

これは実際にモデルの代わりに、その一部DALの型制約に混合型制約とDAL階層を作成しますのでモデルクラスには無効です。

他の定義は、同様の変更を必要とします:

// from 
public class CommentDAL<T> 
    where T : BaseEntity<int>, IBaseDAL<T, int>, ICommentDAL<T> 
// to 
public class CommentDAL<T> : BaseDAL<T, int>, ICommentDAL<T> 
    where T : BaseEntity<int> 
// or to 
public class CommentDAL : BaseDAL<PageComment, int>, ICommentDAL 

あなたが明示的にとにかくCommentDAL内部PageCommentで動作するので(PageComment pc = new PageComment() ...)私はCommentDALレベル上の任意の一般的なパラメータを指定せずに、デザインを選ぶでしょう。

+0

おかげでたくさんの.. @ grek40 [BR] [コード] パブリックインターフェイスIMyClass T:BaseY 、IBaseX [コード] [BR] しかし、あなたが言ったように、第2ない... [BR ] 私は理解できません: "代わりに、あなたの構造を意味するために、BaseXとBaseYは継承階層にある必要があり、より派生したクラスの制約を書くことができます。「MehmetGenç__if__ 'BaseY ' @ –

+0

は 'class' __and__' Tである:BaseY '' __and__ T:BaseX '必要とされる( 'T'は、両方のクラスから派生)、'と 'BaseY __then__' 'BaseX同じ継承階層の一部でなければならないし、C#が多重継承を許さないため_これは 'BaseY :BaseX ' __or__ 'BaseX :BaseY 'が真でなければならないことを意味し、 (これらの2つの間の階層に中間クラスがあるかもしれませんが、一方は他のクラスの祖先でなければなりません) – grek40

+0

@MehmetGenç私の更新を参照してください – grek40

0
public interface IMyClass<T, I> 
    where T : IBaseX<T, I> 
{ } 
IBaseX<T, I>

によれば、TがタイプBaseY<I>であるように制約されるので、これは失敗します。ただし、IMyClass<T, I>の定義にはその制約がないため、Tの制限は適用されません。制約を推移

注意が引き継がれていない、とあなたは明示的に再びそれらをリストする必要があります。

public interface IMyClass<T, I> 
    where T : BaseY<I>, IBaseX<T, I> 
{ } 

は同様に、あなたもMyClass<T, I>ためTのための制約を指定する必要があります。ただし、両方のクラスであるBaseX<T, I>BaseY<I>の両方に制約があるため、.NETでは複数の継承がサポートされていないため、これは機能しません。あなたはしかしIBaseX<T, I>インタフェースを使用することができます。

public class MyClass<T, I> 
    where T : BaseY<I>, IBaseX<T, I>, IMyClass<T, I> 
{ } 
関連する問題