You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在多个后台页面与类之间共享依赖Page类的代码

问题:ASP.NET页面与多类共享依赖Page对象代码时遇空引用错误

我需要在多个Code Behind页面和多个类之间共享依赖Page类对象与方法(如Response、Session、GridView、Panel等)的代码,将这类通用代码存入多个共享类实现复用。

按照建议实现示例代码后,发现从Class1调用Class2_Procedure时会触发“Object reference not set to an instance of an object”错误;但直接从页面调用Class1_Procedure和Class2_Procedure却能正常运行。

示例代码

页面代码

Partial Class _default
    Inherits System.Web.UI.Page

    Dim MyClass1 As New Class1(Me)
    Dim MyClass2 As New Class2(Me)

    Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        Response.Write("Default Page > Page_Load<br/>")
        MyClass1.Class1_Procedure()
        MyClass2.Class2_Procedure()
        MyClass1.Class1_Procedure_Calling_Class2_Procedure()
    End Sub
End Class

Class1代码

Public Class Class1
    Dim MyPage As Page

    Sub New(MePage As Page)
        MyPage = MePage
    End Sub

    Dim MyClass2 As New Class2(MyPage)

    Sub Class1_Procedure()
        MyPage.Response.Write("Class1 > Class1_Procedure<br/>")
    End Sub

    Sub Class1_Procedure_Calling_Class2_Procedure()
        MyPage.Response.Write("Class1 > Class1_Procedure_Calling_Class2_Procedure<br/>")
        MyClass2.Class2_Procedure()
    End Sub
End Class

Class2代码

Public Class Class2
    Dim MyPage As Page

    Sub New(MePage As Page)
        MyPage = MePage
    End Sub

    Sub Class2_Procedure()
        MyPage.Response.Write("Class2 > Class2_Procedure<br/>")
    End Sub
End Class

问题原因与解决方案

错误根源

在Class1中,Dim MyClass2 As New Class2(MyPage)属于类级字段的初始化代码,它的执行顺序早于类的构造函数Sub New。也就是说,当创建MyClass2实例时,MyPage还没被构造函数赋值,此时MyPage是Null,传递给Class2的构造函数后,Class2里的MyPage自然也是Null,调用Class2_Procedure时就会触发空引用错误。

修正方案

把MyClass2的初始化逻辑移到构造函数内部,确保MyPage已经被赋值后再创建Class2实例:

Public Class Class1
    Dim MyPage As Page
    Dim MyClass2 As Class2 ' 先声明字段,暂不初始化

    Sub New(MePage As Page)
        MyPage = MePage
        MyClass2 = New Class2(MyPage) ' 构造函数内完成初始化,此时MyPage已有有效值
    End Sub

    Sub Class1_Procedure()
        MyPage.Response.Write("Class1 > Class1_Procedure<br/>")
    End Sub

    Sub Class1_Procedure_Calling_Class2_Procedure()
        MyPage.Response.Write("Class1 > Class1_Procedure_Calling_Class2_Procedure<br/>")
        MyClass2.Class2_Procedure()
    End Sub
End Class

可选优化:延迟初始化

如果不想在构造函数里提前初始化MyClass2,也可以用延迟初始化的方式,在第一次使用时再创建实例:

Public Class Class1
    Dim MyPage As Page
    Private _myClass2 As Class2

    ' 通过属性实现延迟初始化
    Private ReadOnly Property MyClass2 As Class2
        Get
            If _myClass2 Is Nothing Then
                _myClass2 = New Class2(MyPage)
            End If
            Return _myClass2
        End Get
    End Property

    Sub New(MePage As Page)
        MyPage = MePage
    End Sub

    Sub Class1_Procedure()
        MyPage.Response.Write("Class1 > Class1_Procedure<br/>")
    End Sub

    Sub Class1_Procedure_Calling_Class2_Procedure()
        MyPage.Response.Write("Class1 > Class1_Procedure_Calling_Class2_Procedure<br/>")
        MyClass2.Class2_Procedure() ' 第一次调用时才初始化
    End Sub
End Class

额外建议

  • 降低耦合:可以定义一个IPageContext接口,只暴露业务需要用到的Page成员(如Response、Session),然后让Page实现这个接口,再传递接口实例给共享类,避免直接依赖整个Page对象。
  • 依赖注入:如果项目规模较大,可使用依赖注入框架(如Autofac、Unity)来管理Page相关对象的注入,减少手动传递的代码。

内容的提问来源于stack exchange,提问作者ptownbro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 20:17:03