传递忽略其参数的泛型方法?
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 接受 TArg
的 Func
。在代码中:
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);
但是,根据您对问题的描述,我看不出这些有什么帮助,也看不出如何实现您的要求。也许您需要提供更多关于您试图解决的潜在需求的详细信息?
有没有办法以通用方式传递方法名称,而不传递其参数,以便方法可以通过传递的参数调用它?
考虑这个例子:
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 接受 TArg
的 Func
。在代码中:
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);
但是,根据您对问题的描述,我看不出这些有什么帮助,也看不出如何实现您的要求。也许您需要提供更多关于您试图解决的潜在需求的详细信息?