来自Getter的VB.NET Call Setter

时间:2011-07-29 16:08:38

标签: vb.net properties setter getter

我有一个这样的课程:

Public Class MyClass

Private _intList As New List(Of Integer)
Private _avg As Decimal

Public Sub Add(ByVal anInt As Integer)
    _intList.Add(anInt)
End Sub

Public Property Avg() As Decimal
    Get
        Dim _sum As Integer = 0
        For Each anInt In _intList
            _sum += anInt
        Next
        Avg = If((_intList.Count > 0), _sum / _intList.Count, _avg)
        Return _avg
    End Get
    Set(ByVal value As Decimal)
        If _avg <> value Then
            _avg = value
            Console.WriteLine("Value changed")
        End If
    End Set
End Property

End Class

Getter正在计算平均值并调用Setter来保存该值。由于某种原因,我无法理解,平均值始终为0.例如:

Dim c As New Class2()
c.Add(1)
c.Add(2)
c.Add(3)
Console.WriteLine(c.Avg.ToString()) ' This will print 0

我做错了什么吗?造成这种情况的原因是什么?

4 个答案:

答案 0 :(得分:6)

哇,我认为你发现了VB的非常奇怪的行为:当你进入函数的定义时,你可以用{返回 的值 {1}} 使用Return“设置”函数的值。

像这样:

=

在上述函数中,行Function GetInteger() As Integer GetInteger = 5 End Function 基本上等同于GetInteger = 5 *。

好的,所以你可能已经知道了。但这是奇怪的部分,我不知道这是直到现在测试它的情况(诚然,在Mono,但我看到你的行为相同):显然这适用于属性获取者以及。所以看看这一行:

Return 5

你实际上没有在那里调用属性设置器;你正在为getter设置返回值。您可以通过删除第Avg = If((_intList.Count > 0), _sum / _intList.Count, _avg) 行来验证这一点;突然你会看到你的吸气剂开始返回实际的平均值。

* 完全相同,因为您可以稍后将Return _avg设置为其他内容而不立即返回,而使用GetInteger可确保函数立即返回。 /子>

答案 1 :(得分:4)

这是设计并在Visual Basic语言规范第9.7.1章中明确提到:

  

一个特殊的局部变量,在Get中隐式声明   存取主体的声明空间与属性同名,   表示属性的返回值。局部变量有   表达式中使用时的特殊名称解析语义。如果   局部变量用于需要表达式的上下文中   然后分类为方法组,例如调用表达式   名称解析为函数而不是局部变量。   例如:

ReadOnly Property F(i As Integer) As Integer
    Get
        If i = 0 Then
            F = 1    ' Sets the return value.
        Else
            F = F(i - 1) ' Recursive call.
        End If
    End Get
End Property

直接指定_avg字段解决您​​的问题。最好避免使用像这样的副作用的财产获取者。

答案 2 :(得分:1)

你的setter和getter真的应该只返回属性,而不是自己进行计算。尝试创建一个像calcAvg()那样执行平均计算的方法,并在Add()调用该方法(这应该在内部不会重新执行整个平均计算,但只是更新它。请告诉我,如果你'我不知道该怎么做)。 calcAvg()方法将设置_avg实例变量。

另外,我不确定它是否真的让send有一个平均的setter。数字的平均值是派生属性,而不是应由外部用户设置的属性。

答案 3 :(得分:0)

MrDanA回答比我要给你的更正确,但是,我相信你得到0值的原因是因为你永远不会将变量_avg设置为任何东西。如果你这样做了AVG计算:

_avg = AVG return _avg

当我这样做时,我的值为2.

就像我之前说过的那样...... MrDanA的答案是一个更好的方法。