简体   繁体   中英

Generic methods with delegate parameters

I'm trying to create two generic methods, one of them is void and the other has a return type. The void method takes an Action delegate, and the other one takes a Func delegate. The implementation for the void method is like this:

 public static void ExecuteVoid<T>(Action<T> actionToExecute)
    {
        string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(T));

        using (ChannelFactory<T> factory = new ChannelFactory<T>(new BasicHttpBinding(), new EndpointAddress(endpointUri)))
        {
            T proxy = factory.CreateChannel();

            actionToExecute(proxy);
        }
    }

This works fine, but I'm having issues with the non-void method:

public static T ExecuteAndReturn<T>(Func<T> delegateToExecute)
    {
        string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(T));

        T valueToReturn;

        using (ChannelFactory<T> factory = new ChannelFactory<T>(new BasicHttpBinding(), new EndpointAddress(endpointUri)))
        {
            T proxy = factory.CreateChannel();

            valueToReturn = delegateToExecute();
        }

        return valueToReturn;
    }

Now when I try to make a call to the method like this:

var result = ServiceFactory.ExecuteAndReturn((IMyService x) => x.Foo());

I get this compile error:

The type arguments for method 'ServiceFactory.ExecuteAndReturn<T>(System.Func<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Foo() in this case is a method with no arguments that returns an object . I then tried to call the method by specifying the type explicitly:

var result = ServiceFactory.ExecuteAndReturn<IMyService>(x => x.Foo());

but now I'm getting another exception saying

Delegate 'IMyService' does not take 1 arguments.

I'm really lost here. Any help is appreciated.

You might be confusing the return type with the proxy type. If you specify your argument as Func<T> , then T needs to be the return type of the function, not the proxy type. However, you also need to specify the proxy type, in order to get the proper service endpoint and channel factory. Thus, you actually need two type parameters: one for the proxy and one for the return type. I'm also assuming that the function delegate needs to take the initialized proxy as parameter; otherwise, this wrapper method would be pointless.

public static TResult ExecuteAndReturn<TProxy, TResult>(
    Func<TProxy, TResult> delegateToExecute)
{
    string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(TProxy));

    TResult valueToReturn;

    using (ChannelFactory<TProxy> factory = new ChannelFactory<TProxy>(new BasicHttpBinding(), new EndpointAddress(endpointUri)))
    {
        TProxy proxy = factory.CreateChannel();

        valueToReturn = delegateToExecute(proxy);
    }

    return valueToReturn;
}

Edit : The compiler error arose because (IMyService x) => x.Foo() is not compatible with the Func<T> delegate. When writing anonymous functions, the inferred type is that of the anonymous function itself, not the method it happens to call. In this case, the anonymous function accepts a single parameter of type IMyService , and returns object (being the return type of Foo ). Thus, the correct delegate for this anonymous method would be Func<IMyService, object> .

您已将参数定义为func<x>即没有参数的委托,然后将其称为Func<x,y> ,即将其接受1个参数IMyService的委托,因此错误“ Delegate'IMyService'不接受1个参数“

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM