有没有办法以通用方式传递方法名称,而不传递其参数,因此可以通过传递参数调用方法?
考虑这个例子:
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
是一个外部密封类,它暴露了许多参数中的每一个的大量方法。我想要包装它的行为,我不介意在包装器中编写所有必要的代码,但包装器的使用应该尽可能干净。
更新
我想避免指定参数。整个想法是从指定的行动中推断出来。
答案 0 :(得分:2)
您希望传递给Invoke
的表达式返回接受Func
的{{1}}。在代码中:
TArg
然后您可以这样调用它:
public class Wrapper<TClient>
{
TClient Client;
public TResult Invoke<TArg, TResult>(Func<TClient, Func<TArg, TResult>> action, TArg arg)
{
return action(Client)(arg);
}
}
由于您不喜欢必须明确指定类型参数的方法,您可以使用稍微不同的API(它带有自己的烦恼):
class Program
{
static void Main(string[] args)
{
var wrapper = new Wrapper<Client>();
string result = wrapper.Invoke<int, string>(c => c.Convert, 5);
}
}
您可以这样调用,使用从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
答案 1 :(得分:2)
您非常接近让代码运行。有两种选择。
首先,你可以试试这个:
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);
但是,根据您对问题的描述,我不知道其中任何一个是如何帮助的,而我也不知道如何实施您的问题。也许你需要提供更多细节,说明你需要解决的潜在需求是什么?