5

任何人都知道为什么这不起作用(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)

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

这是每个建议的单元测试:

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)
4

3 回答 3

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 中混合了两种样式。设置该变量不会调用设置器;它通知运行时当 getter 返回时,这是它应该返回的值。然后,您用您的Return语句覆盖该值。

如果你这样做时很痛,那就不要那样做

于 2012-04-25T16:10:43.030 回答
4

在单元测试中对我来说很好;尽管在 C# 中(见下文)。

(玩了一段时间后)

啊明白了!这是因为您正在调用CustomTextFormatter = Nothingwhich,在 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);
    }
于 2012-04-25T15:55:42.660 回答
-3

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

Private itsCustomTextFormatter As String = "Something"
于 2012-04-25T15:54:03.960 回答