VS2010 Внедрение расширения Generic Interface не использует указанный тип - PullRequest
3 голосов
/ 15 апреля 2010

В выпускной версии Visual Studio 2010 я думаю, что есть разница в расширении "Интерфейс реализации" по сравнению с VS2008

Если я укажу интерфейс и реализую его в классе следующим образом:

public interface IRepository<T> where T : IModel
{
    T Get<T>(int id);
    void Update<T>(T item);
    int Add<T>(T item);
}    

public class MockRepository : IRepository<MockUser>
{
// ...
}

Затем используйте расширение "Implement Interface" и получите это:

public class MockRepository : IRepository<MockUser>
{
    public T Get<T>(int id)
    {
        throw new NotImplementedException();
    }

    public void Update<T>(T item)
    {
        throw new NotImplementedException();
    }

    public int Add<T>(T item)
    {
        throw new NotImplementedException();
    }
}

Вместо того, что я ожидал

public class MockRepository : IRepository<MockUser>
{
    public MockUser Get<MockUser>(int id)
    {
        throw new NotImplementedException();
    }

    public void Update<MockUser>(MockUser item)
    {
        throw new NotImplementedException();
    }

    public int Add<MockUser>(MockUser item)
    {
        throw new NotImplementedException();
    }
}

В среде IDE используется имя переменной типа из определения общего интерфейса T вместо указанного конкретного типа MockUser. Это ошибка? Или что-то новое только для VS2010 / .Net 4.0?

Обновление: Это НЕ ошибка, я не указал интерфейс, как я предполагал, он должен быть определен как:

public interface IRepository<T> where T : IModel
{
    T Get(int id);
    void Update(T item);
    int Add(T item);
}    

другими словами, мне не нужно было указывать параметр Type T на уровне интерфейса и метода, а только на интерфейсе.

Ответы [ 2 ]

4 голосов
/ 15 апреля 2010

Это делает именно то, что вам нужно.

Каждый из методов вашего интерфейса имеет свой собственный параметр T, который до сих пор не указан, пока вызывающий метод не определит его. Ваш интерфейс T не используется.

4 голосов
/ 15 апреля 2010

Нет смысла <T> в качестве параметра типа для методов интерфейса. В этом нет необходимости, и если вы удалите его, вы получите ожидаемое поведение - за исключением того, что результат будет следующим:

public class MockRepository : IRepository<IModel>
{
    public IModel Get(int id)
    {
        throw new NotImplementedException();
    }

    public void Update()
    {
        throw new NotImplementedException();
    }

    public int Add(IModel item)
    {
        throw new NotImplementedException();
    }
}

Параметры общего типа метода отличаются от параметров типа интерфейса / класса - я бы не ожидал, что они будут реализованы с использованием IModel в вашем примере. (Другими словами, T в IRepository<T> не является T в Get<T>.)

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