关于.Net中属性的使用探讨(二)

关于.Net中属性的使用探讨(二)

codeprince  http://tangyong.net@163.com

三.编写Get过程中需要注意的问题

     当定义一个标量属性的时候,如上面所定义的CityName,这是一个既可读又可写的属性,当然你可以将它定义为只读的属性。我们需要考虑如何去编写get过程。(更多的人是和我开始的时候一样,什么都不做,写一个return语句,我要说这是安全的,但我们还需要了解其他一些东西)。我要说的第一个问题是:Get函数不应该有任何明显的副作用,换句话说,你对Get过程的定义不能影响到这个类的对象状态,比如说你编写CityName这个属性,但你又想通过CityName反映城市与城市之间的某种关系,这样就会增加CityName的副作用,这是不好的行为。为什么呢?这是因为调用Get过程在逻辑上与访问字段类似,如果我们发现了自己在Get函数中更新了状态,那么我的建议(也是Andy Olsen等专家的建议)是将这个Get过程实现为方法。方法是可以也是经常会产生副作用的。

      也许有人会说既然这样,方法不是可以取代属性了吗,还要它干吗?这本身就是一种替代和包含的关系吗!其实有的时候我也这么想,但我要说有三种情况也许会打动你的心从而使用属性。

1.  要获取类中现有的字段值。在这种情况下,Get函数只作为已经在类中出现的一块数据的包装器。Get函数直接返回私有字段的值。(这也是我们最为经常遇到的)

2.   要计算类中的派生值。在这种情况下,Get过程使用类中的数据来计算新的值,对于面向对象的分析和设计来说,这叫做类的派生特性。

3.   要执行“懒惰”初始化。(也就是推迟初始化类中的私有字段)在这种情况下,类有一个很少使用的字段,或者说有些字段在创建对象时,你无法预计它的值(当然由编译器可以指派一个默认的值),为了效率,我们可以推迟初始化这个字段,直到它通过Set过程(或其他的方法显示地赋值)。当用户需要这个字段时,我们再通过Get过程得到。如果客户应用程序永远不请求这个字段,那么我们也就永远不用计算它,这样就提高了性能。

下面分析一个例子:

      Class City

           private mCityName as String          '城市的名称

           private mBuildTime as DateTime   '城市的修建时间

           private  mChargedRegionSquares as String  '城市所管辖的地域面积

           public Sub New(Byval CityName as String,Byval BuildTime as DateTime)

                mCityName=CityName

                mBuildTime=CityHistory

                mChargedRegionSquares="<Not Read>"

            End Sub

            public Property CityName() as String

                  Get

                        Return mCityName

                   End Get

                   Set(Byval Value as String)

                         mCityName=Value

                    End Set

              End Property

              'CityHistory属性代表了城市已存在的时间
              Public ReadOnly Property CityHistory() as Integer   

                   Get

                        Dim Today as DateTime=DateTime.Now

                        Dim Years as Integer=DateTime.Now.Year-mBuildTime.Year

                        if (Today.Month<mBuildTime.Month) or  

                             (Today.Month=mBuildTime.Month and

                                     Today.Day<mBuildTime.Day)    then

                               Years-=1

                         End If

                         Return Years

                    End Get

               End Property

               public ReadOnly Property ChargedRegionSquares() as String

                      Get

                            if (mChargedRegion="<Not Read>" then

                                  Dim Conn as OleDbConnection

                                  Dim Cmd as OleDbCommand

                                 Try

                                        Conn=New OleDbConnection("Provider=........."&_

                                                 "DataSource=City.mdb")

                                         Cmd=New OleDbCommand("Select RegionSquares From

                                                     CityRegions Where CityName='"&mName&"'",

                                                      Conn)

                                           mChargedRegionSquares=Cmd.ExecuteScalar()

                                           if mCharedRegionSquares is Nothing then

                                                 mChargedRegionSquares="<UnKnown>"

                                           end If

                                    Catch Ex as OleDbException

                                            Console.Writeln("Error occurred:{0}",Ex.Message)

                                    Finally

                                           if Not Conn is Nothing Then

                                                 Conn.Close()

                                            End If

                                     End Try

                            End If

                      Return mChargedRegionSquares

               End Get

          End Property

      End Class

我们现在来分析上面的代码:(对于上面的代码中用到了数据库的连接,需要我们显示地Imports System.Data.OleDb,这是必须的。)

1.  City类有表示城市的名称,城市的修建时间,城市的管辖地域这三个私有字段。

2.   构造函数初始化城市的名称和城市的修建时间这两个私有字段,并且将城市的管辖地域初始化为<Not Read>,用来指示将在第一次读取数据库时被读取到。

3.   CityName属性获取和设置mCityName字段,而没有更深的处理,这个属性很薄地封装了mCityName的属性。

4.   CityHistory属性根据城市的修建时间和当前的系统时间来计算这个城市的存在时间。这是一个很明显的派生特性的例子。注意:每次都重新计算CityHistory似乎比把这个时间存在字段里要合适的多。

5.   ChargedRegionSquares属性可以进行懒惰初始化。在上面的例子中,城市管辖的地域存在数据库中,所以我们在构造函数中就不要对它求值,因为这样就可以当客户代码需要用到这个属性时,就与数据库连接来获得。这样明显提高了效率。

6.   我们在上面的代码中加入了错误和异常的处理,这对于一个健壮的面向对象的程序来说是必要的,相信大家和我有同感吧。

                           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VB.NET是一种高级的编程语言,可以用它来访问Modbus TCPIP通信协议。Modbus TCPIP是一种常用的工业通讯协议,常用于PLC和其他设备之间进行通信。在VB.NET,我们可以使用Modbus TCP类库来轻松地实现Modbus TCPIP通信。在本文,我们将探讨如何使用VB.NET来实现Modbus TCPIP通信以及如何使用Modbus TCP类库来实现这一过程。 1.引入Modbus TCP类库 Modbus TCP类库包含了许多关于Modbus TCP通信的类、方法和属性等。要使用这个类库,我们需要将其添加到我们的VB.NET项目。我们可以从Nuget上安装ModbusTCP.dll包来引入这个类库。 2.连接到Modbus服务器 在VB.NET,我们可以使用一个叫做TcpClient的类来连接到Modbus服务器,如下所示: Dim client as New TcpClient("192.168.1.1", 502) 如果连接成功,我们可以使用这个客户端来发送和接收Modbus TCPIP数据。如果连接失败,我们需要处理异常或者重新连接。 3.发送Modbus TCPIP指令 Modbus TCPIP协议将数据交换定义为读或写操作,并且每个操作都指定了一个数据地址和数据长度。我们可以使用Modbus TCP类库的Write方法来发送Modbus TCPIP指令,如下所示: Dim cmd as New WriteMultipleCoilsRequest(1, 0, {True, False, True}, 3) client.GetStream().Write(cmd.MessageFrame, 0, cmd.MessageFrame.Length) 上面的代码将向Modbus服务器发送一个指令,该指令将地址1处的3个连续线圈写为True、False、True。发送指令后,我们可以使用Read方法来读取Modbus服务器返回的数据。 4.接收Modbus TCPIP响应 Modbus TCPIP响应包含了指令的执行结果和相关数据。我们可以使用Modbus TCP类库的Read方法来接收Modbus TCPIP响应,如下所示: Dim rsp as ModbusTCP.Message.IMessage rsp = ModbusTCP.Message.ReadResponse(client.GetStream()) 如果响应成功,我们可以从响应获取相关数据,如: Dim coils() as Boolean = DirectCast(rsp.Data, ModbusTCP.Message.ReadCoilsResponse).Data 上面的代码将获取Modbus服务器返回数据的线圈值,并存储在一个Boolean数组。 总之,VB.NET是一种非常强大的编程语言,可以用来实现复杂的Modbus TCPIP通信任务。使用Modbus TCP类库可以轻松地发送和接收Modbus TCPIP指令和响应,因此我们可以在开发PLC、控制器等设备的应用程序时,更加方便地实现数据交换。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值