【问题标题】:Is there any way to inherit a class without constructors in .NET?有没有办法在.NET中继承一个没有构造函数的类?
【发布时间】:2010-09-28 20:54:49
【问题描述】:

我目前正在尝试修改一些 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();
        }
    }
}

【问题讨论】:

    标签: c# .net inheritance httpwebrequest


    【解决方案1】:

    除非你可以欺骗序列化构造函数来做你的投标,否则没有,没有办法。

    该类的构造函数是内部的,因此您无法调用它们。

    【讨论】:

    • 不能使用下面的解决方案吗? stackoverflow.com/questions/178645/…
    • 嗯,你当然可以使用反射和类似的东西,但从长远来看,这确实会导致更多的问题。您正在绕过类的所有配置,这可能意味着它根本不处于一致状态。
    • 如果想作恶,可以声明一个派生类Foo,其构造函数类似于Foo(int x) : Foo( ((String)null).Length ) { },而析构函数将this 复制到静态位置。尝试构造实例,捕获异常,强制收集,等待挂起的终结器,静态位置将保存派生类的实例,而没有任何基类构造函数运行。
    • @supercat 不幸的是,构造函数调用中不能有循环。
    • @IS4:我在上面没有看到任何循环。
    【解决方案2】:

    您不能通过 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();
            }
    
        }
    }
    

    【讨论】:

    • 他也可以使用该方法通过反射将调用委托给序列化构造函数。
    • 这种方法+1。我通常更喜欢组合而不是继承。
    猜你喜欢
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 2017-10-04
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多