.NET의 생성자없이 클래스를 상속하는 방법이 있습니까?
-
03-07-2019 - |
문제
현재 일부 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();
}
}
}
해결책
직렬화 생성자를 속일 수 없다면 입찰을 수행 할 수 없습니다. 그렇지 않으면 방법이 없습니다.
해당 클래스의 생성자는 내부이므로 전화 할 방법이 없습니다.
다른 팁
You can't through inheritance from HttpWebRequest (if you don't want to call the serialization constructor) , but you can through composition and delegation, and through inheritance from WebRequest (I'm not sure if that will do it for you, but functionally it is quite similar). WebRequest has a default constructor.
In this case you then can't have the class 'be' a HttpWebRequest (as in an is-a relationship), since you can't extend from it, but it wil 'be' a WebRequest, which should suffice.
You could write a class that inherits from WebRequest, that has an instance member of type WebRequest, create a HttpWebRequest and assign to instance member in the constructor of the new type and delegate all calls to that reference (sort of a decorator pattern):
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();
}
}
}