有趣的财产行为

时间:2012-04-25 15:48:27

标签: c# .net vb.net

任何人都有任何想法为什么这不起作用(C#或VB.NET或其他.NET语言并不重要)。这是我的问题的一个非常简化的例子(对不起VB.NET):

    Private itsCustomTextFormatter As String
    Public Property CustomTextFormatter As String
        Get
            If itsCustomTextFormatter Is Nothing Then CustomTextFormatter = Nothing  'thinking this should go into the setter - strangely it does not'
            Return itsCustomTextFormatter
        End Get
        Set(ByVal value As String)
            If value Is Nothing Then
                value = "Something"
            End If
            itsCustomTextFormatter = value
        End Set
    End Property

如果你这样做:

Dim myObj as new MyClass
Console.WriteLine(myObj.CustomTextFormatter)

你会对结果感到惊讶。它将打印“Nothing”。任何人都知道它为什么不打印“Something”

以下是每个建议的单元测试:

Imports NUnit.Framework

<TestFixture()> _
Public Class Test
   Private itsCustomTextFormatter As String
    Public Property CustomTextFormatter As String
        Get
            If itsCustomTextFormatter Is Nothing Then CustomTextFormatter = Nothing 'thinking this should go into the setter - strangely it does not' 
            Return itsCustomTextFormatter
        End Get
        Set(ByVal value As String)
            If value Is Nothing Then
                value = "Something"
            End If
            itsCustomTextFormatter = value
        End Set
    End Property

    <Test()>
    Public Sub Test2()
        Assert.AreEqual("Something", CustomTextFormatter)
    End Sub
End Class

返回:

Test2 : Failed  
  Expected: "Something"
  But was:  null

at NUnit.Framework.Assert.That(Object actual, IResolveConstraint expression, String message, Object[] args)
at NUnit.Framework.Assert.AreEqual(Object expected, Object actual)

3 个答案:

答案 0 :(得分:13)

您的评论:

'thinking this should go into the setter - strangely it does not'    

调出你的错误。在Visual Basic中,有两种方法可以从函数中返回内容:

Function GetSomeValue() As String
    Return "Hello"
End Function

Function GetSomeValue() As String
    GetSomeValue = "Hello"
End Function

混合这两种风格是完全合法的,但令人困惑和不好的做法:

Function GetSomeValue() As String
    GetSomeValue = "Hello" ' I should return Hello... '
    Return "GoodBye"       ' ...or perhaps not. '
End Function

如您所见,您正在混合getter中的两种样式。 设置该变量不会调用setter;它通知运行时当getter返回时,这是它应该返回的值。然后用你的Return语句覆盖该值。

如果你这样做会有伤害,那么就不会这样做

答案 1 :(得分:4)

在单元测试中适合我;虽然在C#中(见下文)。

(经过一些游戏后)

啊得到了!这是因为你正在调用CustomTextFormatter = Nothing,在Getter的范围内实际上只是设置封闭访问器方法的返回值 - 它实际上并没有触发setter(如果你在你的setter中设置一个断点,你会看到并调试它,你会看到它正好在它上面。)

基本上你真的不应该做这种模式;它不是返回默认属性值的方法。这样会更好(或使用与C#??运算符相同的任何东西):

Public Property CustomTextFormatter As String
    Get
        If itsCustomTextFormatter Is Nothing Then
            Return "Something"
        End If
        Return itsCustomTextFormatter

    End Get
    Set(ByVal value As String)
        itsCustomTextFormatter = value
    End Set
End Property

原创C#测试

    private string _foo;
    private string foo
    {
        get
        {
            if (_foo == null)
                foo = null;
            return _foo;
        }
        set
        {
            if (value == null)
                value = "Something";
            _foo = value;
        }
    }

    [TestMethod]
    public void Test()
    {
        Assert.AreEqual("Something", foo);
    }

答案 2 :(得分:-3)

因为你从未真正初始化变量。您必须将该属性“设置”为空,才能实际获得“Something”。要修复它,您应该在声明内部变量时设置默认值

Private itsCustomTextFormatter As String = "Something"