هل هناك أي طريقة لوراثة فصل دراسي بدون مُنشئات في .NET؟

StackOverflow https://stackoverflow.com/questions/400565

سؤال

أحاول حاليًا تعديل بعض وظائف 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 على مُنشئ افتراضي.

في هذه الحالة، لا يمكنك جعل الفصل "يصبح" HttpWebRequest (كما هو الحال في العلاقة "is-a")، نظرًا لأنه لا يمكنك التوسع منه، ولكنه "سيكون" 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();
        }

    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top