【问题标题】:Interface method return type to be class that implements the interface接口方法返回类型为实现接口的类
【发布时间】:2011-05-16 21:52:34
【问题描述】:

我无法理解界面。在这里搜索了类似的问题后,我提出了以下接口,用于定义我所有类所需的 CRUD 操作:

public interface IData<T>
{
    IData<T> Select(int id);
    List<T> SelectMultiple();
    void Insert();
    void Update();
    void Delete();
}

然后在我的部分类中实现:

public partial class Post : IData<Post>
{
    public IData<Post> Select(int id)
    {
        MyDataContext dc = MyDataContext.Create();
        return dc.Posts.Single(p => p.PostID == id);
    }

    public List<Post> SelectMultiple()
    {
        MyDataContext dc = MyDataContext.Create();
        return dc.Posts.ToList();
    }

    // Update() and Delete() declarations
}

这一切都编译得很好,但是如果我尝试使用 Post Select() 方法:

Post p = new Post().Select(1);

失败,无法将类型“IData”隐式转换为“Post”。存在显式转换(您是否缺少演员表?)

这是有道理的,但我如何拥有它以使其不需要演员?我希望 Select 返回一个 Post (但不将 Post 定义为接口级别的返回类型)。我是否误解了界面,或者我可以快速做出改变?

【问题讨论】:

  • 您的Post 似乎在混淆问题;它执行 CRUD 并拥有一个职位。我会把它分成两个类,例如PostPostStorage.
  • 帖子存储在 SQL Server 中,并通过 LinqToSQL DBML 访问。上面的 Post 类是 DBML 中 Post 的部分类。

标签: c# interface partial-classes


【解决方案1】:

您应该显式实现IData&lt;Post&gt;.Select 并为您自己的Select 提供适当的返回值。例如:

IData<Post> IData<Post>.Select(int id)
{
    return Select(id);
}

Post Select(int id)
{
    MyDataContext dc = MyDataContext.Create();
    return dc.Posts.Single(p => p.PostID == id);
}

但是,如果你这样做:

IData<Post> post = new Post();
Post p = post.Select(1);

post.Select(1) 仍然返回 IData&lt;Post&gt;。请参阅Femaref's answer 对接口进行重构以允许这样做。

【讨论】:

    【解决方案2】:

    你想返回 T 类型的东西,而不是 IData&lt;T&gt;,所以只需更改签名(至少我猜这是你想要的,否则你会返回 List&lt;IData&lt;T&gt;&gt;):

    public interface IData<T>
    {
      T Select(int id);
      List<T> SelectMultiple();
      void Insert();
      void Update();
      void Delete();
    }
    

    并适当地实施它:

    public Post Select(int id)
    {
        MyDataContext dc = MyDataContext.Create();
        return dc.Posts.Single(p => p.PostID == id);
    }
    

    如果您只想在 Post 类中实现此行为,请显式实现 IData&lt;T&gt; 接口:

    public partial class Post : IData<Post>
    {
      public Post Select(int id)
      {
          MyDataContext dc = MyDataContext.Create();
          return dc.Posts.Single(p => p.PostID == id);
      }
    
      IData<Post> IData<Post>.Select(int id)
      {
          return Select(id);
      }
    
    }
    

    【讨论】:

      【解决方案3】:

      试试怎么样

      public Post Select(int id)
      {
          MyDataContext dc = MyDataContext.Create();
          return dc.Posts.Single(p => p.PostID == id);
      }
      

      即直接返回Post 而不是IData&lt;Post&gt;

      【讨论】:

      • 那么接口没有实现。
      • 是的,当然你也需要重构它。实际上,上面 SLaks 的答案是相同的想法,但开发得当。
      • 这就是我开始的地方,但它无法编译,因为签名与接口的签名不匹配。
      【解决方案4】:

      您需要更改方法以返回Post 实例,然后添加返回该接口的显式接口实现。

      例如:

      public partial class Post : IData<Post> {
          Post Select(int id) { ... }
          IData<Post> IData<Post>.Select(int id) { return Select(id); }
      }
      

      【讨论】:

      • 这行得通,但是创建一种方法来满足接口和另一种用于实际使用似乎很奇怪。
      • @Lazlow,它比你想象的更频繁。例如在实现IEnumerable&lt;T&gt; 时很常见; IEnumerable GetEnumerator() 只需调用 IEnumerable&lt;T&gt; GetEnumerator()
      猜你喜欢
      • 2011-06-22
      • 2019-02-10
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 2013-07-22
      • 1970-01-01
      • 1970-01-01
      • 2012-10-06
      相关资源
      最近更新 更多