Возвращаемый тип метода интерфейса для класса, который реализует интерфейс - PullRequest
3 голосов
/ 28 ноября 2010

У меня проблемы с настройкой интерфейсов. Пролистав подобные вопросы здесь, я пришел к следующему интерфейсу для определения операций 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 возвращал сообщение (но не определял сообщение как тип возврата на уровне интерфейса). Я неправильно понял интерфейсы, или я могу сделать быстрое изменение?

Ответы [ 4 ]

10 голосов
/ 28 ноября 2010

Вы хотите вернуть что-то типа T, а не IData<T>, поэтому просто измените подпись (по крайней мере, я думаю, это то, что вы хотите, так как вы вернете List<IData<T>> в противном случае):

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<T>:

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 голосов
/ 28 ноября 2010

Вам нужно изменить методы для возврата Post экземпляров, а затем добавить явные реализации интерфейса, которые возвращают интерфейс.

Например:

public partial class Post : IData<Post> {
    Post Select(int id) { ... }
    IData<Post> IData<Post>.Select(int id) { return Select(id); }
}
1 голос
/ 28 ноября 2010

Вы должны явно реализовать IData<Post>.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<Post>.См. Ответ Femaref о рефакторинге интерфейса, чтобы разрешить это.

1 голос
/ 28 ноября 2010

Как насчет попытки

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

, т. Е. Вернуть напрямую Post вместо IData<Post>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...