2017-09-26 98 views
0

鉴于以下接口,我不明白为什么ITransactionConsumer上定义的第二种方法不能编译。编译器抱怨说它不能转换为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类型“通讯交易”不能在泛型类型或方法“PaymentSession <被用作类型参数“通讯交易”通讯交易>”。没有从'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类表示它可以接受的类型参数的约束。您定义的类型参数作为通讯交易,然后指定通讯交易必须实现具有IUSER作为其类型参数的接口ITransaction。但是你又试图声明函数ConsumeTransactionWithTUser其中通讯交易是实现IUSER一种类型的返回类型PaymentSession的。实现接口的类型与接口本身不一样! PaymentSession的类型必须为IUSER凹口 - 是你指定的约束,这也就是为什么编译器抱怨:ITransaction < TUSER>是不一样的ITransaction < IUSER>

为了结束:您在PaymentSession类约束要求泛型类型为类型ITransaction < IUSER>凹口 - 比说,PaymentSession要求泛型类型是通用型的更严格ITransaction接受实施IUser的类型。

+0

这很有效!仍然有点困惑,为什么这是必要的,但这就是我需要的。谢谢,将标记为正确。 – thisextendsthat

+2

一个好的答案应该包括解释以及代码。否则没有人学到任何东西。 – Chris

+0

处理解释 - 将在下次休息时提供。 – Jazimov