Почему в этом коде не работает вывод типов?

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

public interface IFooService
{
    FooResponse Foo(FooRequest request);
}

Я хотел бы выполнить некоторые сквозные задачи при вызове методов для таких служб, как эти; например, я хочу унифицированное ведение журнала запросов, ведение журнала производительности и обработку ошибок. Мой подход состоит в том, чтобы иметь общий базовый класс «Репозиторий» с методом Invoke, который заботится о вызове метода и выполнении других действий вокруг него. Мой базовый класс выглядит примерно так:

public class RepositoryBase<TService>
{
    private Func<TService> serviceFactory;

    public RepositoryBase(Func<TService> serviceFactory)
    {
        this.serviceFactory = serviceFactory;
    }

    public TResponse Invoke<TRequest, TResponse>(
        Func<TService, Func<TRequest, TResponse>> methodExpr,
        TRequest request)
    {
        // Do cross-cutting code

        var service = this.serviceFactory();
        var method = methodExpr(service);
        return method(request);
    }
}

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

public class FooRepository : BaseRepository<IFooService>
{
    // ...

    public BarResponse CallFoo(...)
    {
        FooRequest request = ...;
        var response = this.Invoke(svc => svc.Foo, request);
        return response;
    }
}

я получаю эту ошибку компиляции:

Аргументы типа для метода ... не могут быть выведены из использования. Попробуйте указать аргументы типа явно.

Очевидно, я могу исправить это, изменив свой вызов на:

var response = this.Invoke<FooRequest, FooResponse>(svc => svc.Foo, request);

Но я хотел бы избежать этого. способ переработать код, чтобы я мог воспользоваться преимуществами вывода типов?

Редактировать:

Я также должен упомянуть, что более ранний подход заключался в использовании метода расширения; вывод типов для этого работал:

public static class ServiceExtensions
{
    public static TResponse Invoke<TRequest, TResponse>(
        this IService service, 
        Func<TRequest, TResponse> method, 
        TRequest request)
    {
        // Do other stuff
        return method(request);
    }
}

public class Foo
{
    public void SomeMethod()
    {
        IService svc = ...;
        FooRequest request = ...;
        svc.Invoke(svc.Foo, request);
    }
}
7
задан Jacob 19 April 2012 в 21:10
поделиться