2017-09-26 9 views
0

ITransactionConsumerで定義された2番目のメソッドがコンパイルされない理由は、次のインターフェイスではわかりません。コンパイラはITransaction<IUser>に変換できないと文句を言いますが、TUserIUserです。C#ジェネリックス - ジェネリックインターフェイス変換エラー

public interface ITransactionConsumer 
    { 
     //fine 
     PaymentSession<TTransaction> ConsumeTransaction<TTransaction>(TTransaction transaction) 
      where TTransaction : ITransaction<IUser>; 

     //compile error - TTransaction is not convertable to ITransaction<IUser> 
     PaymentSession<TTransaction> ConsumeTransactionWithTUser<TTransaction, TUser>(TTransaction transaction) 
      where TTransaction : ITransaction<TUser> where TUser : IUser; 
    } 

    public class PaymentSession<TTransaction> 
     where TTransaction : ITransaction<IUser> 
    { 
    } 

    public interface ITransaction<out TUser> 
     where TUser : IUser 
    { 
     TUser User { get; } 
     string Id { get; } 
    } 

    public interface IUser 
    { 
     string Name { get; } 
    } 
+1

「TUser」にクラス制約を追加する必要があるようです。つまり、「where TUser class、IUser」です。 – Lee

+0

は、私は別のコンパイルエラーを取得:重大\tコード\t説明\tプロジェクト\tファイル\tライン\t抑制状態 エラー\t CS0314 \t型「TTransaction」がジェネリック型またはメソッド「PaymentSession <タイプパラメータ「TTransaction」として使用することはできませんTTransaction> 'を選択します。 「TTransaction」から「ITransaction 」へのボクシング変換または型パラメータ変換はありません。 –

答えて

1

違反行をこれに置き換えることはできますか?

PaymentSession<TTransaction> ConsumeTransactionWithTUser<TTransaction, TUser>(TTransaction transaction) 
    where TTransaction : ITransaction<TUser>, ITransaction<IUser> where TUser : IUser; 

編集: それが働いていたので、(私はあなたのコードを意図した期待のために)最も正しいアプローチは、あなたが最初のConsumeTransaction宣言に使用する構文を使用することです:

PaymentSession<TTransaction> ConsumeTransactionWithTUser<TTransaction, TUser>(TTransaction transaction) 
    where TTransaction : ITransaction<IUser>; 

あなたの間違いはPaymentSession戻り値になります。 PaymentSessionクラスは、受け入れることができる型引数の制約を表します。あなたはTTransactionとしてその型の引数を定義した後、TTransactionは、その型パラメータとしてたIUserを持つインタフェースITransactionを実装しなければならないことを指定しました。しかし、あなたはその後、TTransactionたIUserを実装タイプですPaymentSessionの種類を返す関数ConsumeTransactionWithTUserを宣言しようとしました。インタフェースを実装する型は、インタフェース自体と同じではありません! PaymentSessionの型はコンパイラが訴え理由である、あなたが指定した制約である--that たIUserでなければなりません:ITransaction < TUSER>ITransaction <たIUser>と同じではありません。

は締めくくりには:PaymentSessionクラスのあなたの制約が型であるジェネリック型を必要とITransaction <たIUser> --thatのPaymentSessionがジェネリック型であるジェネリック型を必要と言っよりも制限IUserを実装するタイプを受け付けるITトランザクション

+0

それは動作します!それがなぜ必要なのか少し混乱していますが、それが私の必要なものです。ありがとうございます、正しいとマークします。 – thisextendsthat

+2

良い答えは、説明だけでなくコードも含めるべきです。そうでなければ誰も何も学ばない。 – Chris

+0

説明に取り組んで - 次の休憩で提供します。 – Jazimov

関連する問題