我有以下几点代码,分散在我的应用程序中。我真的很喜欢它,并将它放在一个静态类或一些实用程序集的类中,所以我没有所有这些重复。
然而,函数的一小部分是独特的,我不知道如何重构它。
private void callResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response;
// End the get response operation
response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamReader = new StreamReader(streamResponse);
string responseData = streamReader.ReadToEnd();
streamResponse.Close();
streamReader.Close();
response.Close();
ExpectedResponseType regResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<ExpectedResponseType>(responseData);
if (regResponse.ok == "0")
{
//error - handle the msg
//whether the user not loggin or not exist
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(CustomErrorMessage);
});
}
else
{
//check the variables unique to the ExpectedResponseType and do Stuff here;
}
}
catch (WebException e)
{
// Error treatment
// ...
Debug.WriteLine("error " + e);
}
我最好奇的是如何传入“ExpectedResponseType”,这样它可能是任何类,(也就是说,有没有办法传入T?)或者可能是如何触发可以由UI执行的事件线程并妥善处理。
感谢。
编辑:“ExpectedResponseType”或“T”是每种类型的服务器调用的大型类集合。例如,我有LoginResponse,RegisterResponse,GetFilesResponse,UpdateResponse,DownloadResponse等。
答案 0 :(得分:1)
编辑:我已删除了之前的示例,因为它不适用于委托签名。
为了处理特定于类型T的参数的检查,您需要添加一些抽象,最简洁的方法可能是将您的代码包装在一个模板化的类中,该类允许注册委托来处理检查,我确信这是一个特定的模式,但不记得是哪一个:
public class ResponseHandler<T>
{
public ResponseHandler(Action<T> typeSpecificCheckFunction)
{
this.CheckVariables = typeSpecificCheckFunction;
}
Action<T> CheckVariables;
public void callResponseCallback(IAsyncResult asynchronousResult)
{
// stuff
T regResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseData);
CheckVariables(response);
// stuff
}
}
在回答您关于处理大量T的问题时,上面清理过的代码可能会清除它,如果没有,那么这就是泛型的用途 - 只要您知道在每种情况下您期望的是什么。因此,对于您期望的每种类型,您可以将其称为:
var handler = new ResponseHandler<ExpectedResponseType>( response =>
{
// code to check your response properties here
});
xxx.RegisterResponseCallback(handler.callResponseCallback);