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)

あなたは結果に驚くでしょう。「Nothing」と出力されます。「何か」が印刷されない理由は誰にもわかります

提案ごとの単体テストは次のとおりです。

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 では、関数から何かを返す方法が 2 つあります。

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

また

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

これら 2 つのスタイルを混在させることは完全に合法ですが、紛らわしく、悪い習慣です。

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

ご覧のとおり、ゲッターで 2 つのスタイルを混在させています。その変数を設定してもセッターは呼び出されません。これは、getter が返されたときに返すべき値であることをランタイムに通知します。Return次に、その値をステートメントでオーバーライドします。

それをすると痛い場合は、それをしないでください

于 2012-04-25T16:10:43.030 に答える
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);
    }
于 2012-04-25T15:55:42.660 に答える
-3

実際に変数を初期化したことがないためです。実際に「何か」を取得するには、プロパティを何も「設定」する必要があります。それを修正するには、おそらく内部変数を宣言するときにデフォルト値を設定する必要があります

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