【问题标题】:C# interface and generic combination. Want to return <T> instead of its base interfaceC# 接口和泛型组合。想要返回 <T> 而不是它的基本接口
【发布时间】:2012-01-30 11:58:32
【问题描述】:

用我认为是非常简单的一段代码,我自己就开始了。代码胜于雄辩,就是这样。

public interface IResponse
{
    IResult Result { get; set; }
}

public class Response<T> : IResponse
    where T : IResult
{
    public T Result { get; set; } 
    // COMPILER ERROR: Property 'Result' cannot be implemented property from interface 'IResponse'. Type should be 'IResult'.
}

编译器不允许我这样做,因为 IResponse 要求 Result 是 IResult,但是我想利用实现类中的泛型并将结果强输入到 T。这是不可能的,还是我错过了有什么小事吗?

【问题讨论】:

    标签: c# .net generics interface


    【解决方案1】:

    您也必须将 IResponse 设为通用:

    public interface IResponse<T>
        where T : IResult
    {
        T Result { get; set; }
    }
    
    public class Response<T> : IResponse<T>
        where T : IResult
    {
        public T Result { get; set; } 
    }
    

    如果你想保持IResponse 接口没有泛型参数,你可以做得更好。下面有两个接口,其中类也透明地实现了没有泛型参数的接口:

    public interface IResponse
    {
        IResult Result { get; set; }
    }
    
    public interface IResponse<T> : IResponse
        where T : IResult
    {
        T Result { get; set; }
    }
    
    public class Response<T> : IResponse<T>
        where T : IResult
    {
        public T Result { get; set; } 
    
        IResult IResponse.Result
        {
            get { return Result; }
            set { Result = (T)value; }
        }
    }
    

    而且,如果您想更接近您的原始实现,您可以去掉 IResponse&lt;T&gt; 并获得以下内容:

    public interface IResponse
    {
        IResult Result { get; set; }
    }
    
    public class Response<T> : IResponse
        where T : IResult
    {
        public T Result { get; set; } 
    
        IResult IResponse.Result
        {
            get { return Result; }
            set { Result = (T)value; }
        }
    }
    

    【讨论】:

    • 使接口也通用的问题是我在另一个我不希望它强制我指定 T 的类中使用它。
    • 是的,我想到了。这就是为什么我刚刚添加了第二个和第三个选项。
    • 刚刚看到你的更新。看起来不错,什么地方埋在我的脑海里。好东西! :)
    【解决方案2】:

    您应该将 IResponse 设为通用,并将 IResponse 中的 Result 类型更改为传递给此接口的类型参数。

    public interface IResponse<T> where T : IResult
    {
        T Result { get; set; }
    }
    
    public class Response<T> : IResponse<T>
    {
        public T Result { get; set; } 
    }
    

    【讨论】:

      【解决方案3】:

      如果您“只是”想“利用泛型”,则不需要IResponse

      界面正在解决另一个问题,一个与您的愿望不兼容的问题。考虑

      IResponse r = x ? new Response<int>() : new Response<string>();
      r.Result = ... // what type?
      

      所以要么将IResponse 设为通用,要么完全删除它。

      【讨论】:

        【解决方案4】:
        public interface IResponse<T> where T : IResult
        {
            T Result { get; set; }
        }
        
        public class Response<T> : IResponse<T> where T : IResult
        {
            public T Result { get; set; } 
            // NO MORE COMPILER ERROR
        }
        

        【讨论】:

          【解决方案5】:

          试试这个

          public class Response<T> : IResponse
              where T : IResult
          {
              public T Result { get; set; }
              // COMPILER ERROR: Property 'Result' cannot be implemented property from interface 'IResponse'. Type should be 'IResult'. 
          
              IResult IResponse.Result
              {
                  get { return this.Result; }
                  set { this.Result = (T)value; }
              }
          } 
          

          【讨论】:

            猜你喜欢
            • 2016-10-24
            • 1970-01-01
            • 2012-05-25
            • 1970-01-01
            • 2019-05-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多