传递忽略其参数的泛型方法?

Pass generic method omitting its parameters?

有没有办法以通用方式传递方法名称,而不传递其参数,以便方法可以通过传递的参数调用它?

考虑这个例子:

public class Client
{
  public string Convert(int value)
  {
    return value.ToString();
  }
}

public class Wrapper<TClient>
{
  TClient Client;

  public TResult Invoke<TArg, TResult>(Func<TClient, TArg, TResult> action, TArg arg)
  {
    return action(Client, arg);
  }
}

我希望能够将我要调用的 TClient 的方法传递给包装器,并传递实际参数,一般来说:

var wrapper = new Wrapper<Client>();
wrapper.Invoke(c => c.Convert, 5);

是否有任何可能的方法来实现这一目标,而无需对方法名称进行硬编码或失去其通用性(即通过使用 Delegate)?

备注:

Client 是一个外部密封的 class,它公开了无数个方法,每个方法都有许多参数。我想包装它的行为,我不介意在包装器中编写所有必要的代码,但包装器的使用应该尽可能干净。

更新
我想避免指定参数的需要。整个想法是让它们从指定的动作中推断出来。

您希望传递给 Invoke 的表达式 return 接受 TArgFunc。在代码中:

public class Wrapper<TClient>
{
    TClient Client;

    public TResult Invoke<TArg, TResult>(Func<TClient, Func<TArg, TResult>> action, TArg arg)
    {
        return action(Client)(arg);
    }
}

然后您可以像这样调用它:

class Program
{
    static void Main(string[] args)
    {
        var wrapper = new Wrapper<Client>();
        string result = wrapper.Invoke<int, string>(c => c.Convert, 5);
    }
}

由于您不喜欢必须显式指定类型参数的方法,您可以使用稍微不同的 API(它有其自身的烦恼):

public class Wrapper<TClient>
{
    TClient Client;

    public void Invoke<TArg, TResult>(Func<TClient, Func<TArg, TResult>> action, TArg arg, out TResult result)
    {
        return action(Client)(arg);
    }
}

您可以这样调用它,使用从 out 参数推断出的 return 类型:

class Program
{
    static void Main(string[] args)
    {
        var wrapper = new Wrapper<Client>();
        string result;
        wrapper.Invoke(c => c.Convert, 5, out result);
    }
}

您即将获得 运行 的代码。有两种选择。

首先,你可以试试这个:

public class Wrapper<TClient>
{
    public TResult Invoke<TArg, TResult>(Func<TArg, TResult> action, TArg arg)
    {
        return action(arg);
    }
}

然后这样称呼它:

var wrapper = new Wrapper<Client>();    
wrapper.Invoke(wrapper.client.Convert, 5);

或者,您也可以这样做:

public class Wrapper<TClient>
{
    public Wrapper(TClient client)
    {
        this.Client = client;
    }

    private TClient Client;

    public TResult Invoke<TArg, TResult>(Func<TClient, TArg, TResult> action, TArg arg)
    {
        if (operation.Target != Client)
          throw new ArgumentException(nameof(operation));

        return action(this.Client, arg);
    }
}

并这样称呼它:

var client = new Client();
var wrapper = new Wrapper<Client>(client);

wrapper.Invoke((c, a) => c.Convert(a), 5);

但是,根据您对问题的描述,我看不出这些有什么帮助,也看不出如何实现您的要求。也许您需要提供更多关于您试图解决的潜在需求的详细信息?