如何将多个方法(带参数)作为参数传递?

假设我有以下WCF代码:

try { ServiceClient proxy = new ServiceClient(); proxy.ClientCredentials.UserName.UserName = "user"; proxy.ClientCredentials.UserName.Password = "password"; proxy.GetData(2); if (proxy.State = CommunicationState.Opened) { proxy.GetData("data"); } proxy.Close(); } catch (FaultException ex) { // handle the exception } 

而且由于我注意到try … catch和其他逻辑是重复的,更不用说设置WCF调用是昂贵的,我想向这个函数发送许多“方法和参数”。

实质上将GetData(2)GetData("data")作为方法数组传递,并使结果异步或同步返回。

我怎么做到这一点?

我想我可以有两个’ref’对象来处理结果[]和对结果[]的共享锁。 但是我不确定如何将“带参数的方法”作为参数传递给另一个函数。

也许另一种看待它的方法可能是一个函数指针数组,使用不同的参数来表示相同的函数。

任何人都可以推动我做正确的方法吗?

更多信息:

我问这个问题所以我可以优化这种方法来处理WCFexception和重试,但所以我不必总是在每次调用后打开/关闭客户端。

使用委托并在列表中传递它们。

当需要返回值时,使用C# Func委托。

 List> funcList = new List>(); funcList.Add( () => GetData(2) ); // You can use any condition as you otherwise would to add to the list. if (proxy.State = CommunicationState.Opened) { funcList.Add( () => GetData("data") ); } List ProcessFuncs(List> funcDatas) { List returnList = new List(); foreach(var func in funcDatas) { returnList.Add(func()); } } 

(只要返回类型相同,这将有效)

这只是一个例子; 如果你的方法没有返回任何东西,你可以使用C# Action委托,它只执行一个动作而不返回任何值。

 List actionList = new List(); actionList.Add( () => ProcessData("data")); // ProcessData is a void with no return type actionList.Add( () => ProcessData(2)); public void ProcessActions(List actions) { foreach(var action in actions) { action(); } } 

回应一些评论:

此代码编译并完全等效:

 class Program { public static string GetData(string item) { return item; } public static string GetData(int item) { return item.ToString(); } static void Main(string[] args) { string someLocalVar = "what is it?"; int someLocalValueType = 3; Func test = () => { return GetData(someLocalVar); }; Func test2 = () => GetData(someLocalValueType); someLocalValueType = 5; List> testList = new List>(); testList.Add(() => GetData(someLocalVar)); testList.Add(() => GetData(2)); testList.Add(test); testList.Add(test2); someLocalVar = "something else"; foreach(var func in testList) { Console.WriteLine(func()); } Console.ReadKey(); } } 

结果是:

在此处输入图像描述

我不会在这里使用委托,因为那时你受到类型的约束,并解决它变得可怕和过于复杂。 我只需要一个回调,一旦设置好就可以让你自由统治ServiceClient。 我认为这是一个有名字但我不知道的模式。

 interface IProxyActionCallback { void DoProxyStuff(ServiceClient proxy); } void MyMethod(IProxyActionCallback callback) { try { ServiceClient proxy = new ServiceClient(); proxy.ClientCredentials.UserName.UserName = "user"; proxy.ClientCredentials.UserName.Password = "password"; callback.DoProxyStuff(proxy); proxy.Close(); } catch (FaultException ex) { // handle the exception } } 

然后你调用这样的方法:

 MyMethod(new DoSpecificStuff()); 

DoSpecificStuff是一个实现接口的类,允许您使用代理进行特定调用:

 class DoSpecificStuff : IProxyActionCallback { public void DoProxyStuff(ServiceClient proxy) { proxy.GetData(2); if (proxy.State = CommunicationState.Opened) { proxy.GetData("data"); } } } 

所以你有很多实现接口的类,它们都“共享”同一个地方的try-catch样板代理。

Bellow是一个如何创建委托集合及其参数的示例,然后在不知道方法定义的情况下稍后调用它们。 据我所知,如果你想在一个通用调用中调用具有不同定义的方法,你必须做这样的事情。

  List> delegates = new List>(); delegates.Add(new Tuple(new Func(MyFunctionName), new object[] { arg1, arg2 }); foreach (Tuple d in delegates) { d.Item1.DynamicInvoke(d.Item2); } 

您可以使用C#委托:

委托是一种类型,表示对具有特定参数列表和返回类型的方法的引用。 实例化委托时,可以将其实例与具有兼容签名和返回类型的任何方法相关联。 您可以通过委托实例调用(或调用)该方法。 委托用于将方法作为参数传递给其他方法。 事件处理程序只不过是通过委托调用的方法。 您可以创建自定义方法,并且诸如Windows控件之类的类可以在发生特定事件时调用您的方法。 以下示例显示了委托声明:

更多相关信息: http : //msdn.microsoft.com/en-us/library/ms173171.aspx

您可以通过以下方式传递函数:

 public void strategy(Func f); public bool predicate(string a, string b); strategy(predicate); 

第一行声明函数strategy()接受函数f ; 该函数返回类型R并采用T1T2类型的两个参数。

第二行定义了一个返回bool并接受两个string的函数。

第三行调用策略将谓词作为参数传递给它。

不确定要了解您要实现的目标,但基本上如果您的服务公开GetData(int)方法和GetData(string)方法以及异步代理,您应该使用以下内容异步调用它们:

 var getData = proxy.GetDataAsync(2); var getData2 = proxy.GetDataAsync("data"); await Task.WhenAll(getData, getData2); // Gets the result using getData.Result...etc.