Ответ 1
Если вы не можете обмануть конструктор сериализации для выполнения своих ставок, тогда нет, нет способа.
Конструкторы этого класса являются внутренними, поэтому вы не можете их называть.
В настоящее время я пытаюсь изменить некоторые функции HttpWebRequest, но я не могу сделать это через наследование, потому что HttpWebRequest не имеет общих конструкторов (кроме конструктора десериализации). Есть ли способ обхода этого?
Моя цель - закодировать что-то вроде приведенного ниже примера, но объекты этого класса должны наследовать свойства и методы HttpWebRequest:
using System;
using System.Net;
using System.Threading;
public class AsyncWebRequest:WebRequest
{
private readonly AsyncCallback getResponseCallback;
private readonly Uri uri;
private volatile int RetriesLeft = 3;
private volatile WebRequest request;
public AsyncWebRequest(string uri, AsyncCallback getResponseCallback)
:this(new Uri(uri), getResponseCallback)
{
}
public AsyncWebRequest(Uri uri, AsyncCallback getResponseCallback):base()
{
this.uri = uri;
this.getResponseCallback = getResponseCallback;
}
private IAsyncResult BeginGetResponse()
{
request = HttpWebRequest.CreateDefault(uri);
((HttpWebRequest)request).ReadWriteTimeout = Timeout;
var result = request.BeginGetResponse(GetResponseCallback, null);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle,
GetResponseTimeout, null, Timeout, true);
return result;
}
private void GetResponseTimeout(object state, bool timedOut)
{
if (timedOut)
{
Retry();
}
}
private void Retry()
{
request.Abort();
bool retry = false;
lock (request)
{
if (RetriesLeft > 0)
{
Interlocked.Decrement(ref RetriesLeft);
retry = true;
}
}
if (retry)
{
BeginGetResponse();
}
else
{
getResponseCallback(null);
}
}
private void GetResponseCallback(IAsyncResult AsyncResult)
{
try
{
getResponseCallback(AsyncResult);
}
catch(WebException webException)
{
Retry();
}
}
}
Если вы не можете обмануть конструктор сериализации для выполнения своих ставок, тогда нет, нет способа.
Конструкторы этого класса являются внутренними, поэтому вы не можете их называть.
Вы не можете наследовать из HttpWebRequest (если вы не хотите вызывать конструктор сериализации), но вы можете с помощью композиции и делегирования, а также через наследование из WebRequest (я не уверен, что это сделает это для вы, но функционально это очень похоже). У WebRequest есть конструктор по умолчанию.
В этом случае у вас тогда не может быть класса 'be' HttpWebRequest (как в отношениях is-a), так как вы не можете продлевать его, но это wil 'be' WebRequest, которого должно хватить.
Вы можете написать класс, который наследует от WebRequest, который имеет экземпляр-тип типа WebRequest, создает HttpWebRequest и присваивает члену экземпляра в конструкторе нового типа и делегирует все вызовы этой ссылке (вид шаблона декоратора ):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
namespace ClassLibrary1
{
public class MyHttpWebRequest : WebRequest
{
private WebRequest request;
public MyHttpWebRequest(string uri)
{
request = HttpWebRequest.Create(uri);
}
public override WebResponse GetResponse()
{
// do your extras, or just delegate to get the original code, as long
// as you still keep to expected behavior etc.
return request.GetResponse();
}
}
}