How can I revert a property to its default value?

Solution 1:

Here's an example of how you ought to do this with an actual default value:

Imports System.ComponentModel

Public Class Thing

    <DefaultValue("Hello World")>
    Public Property WithDefault As String

    Public Property WithoutDefault As String

End Class
Imports System.ComponentModel
Imports System.Reflection

Module Module1

    Sub Main()
        Dim something As New Thing

        something.WithDefault = "First"
        something.WithoutDefault = "Second"

        If TrySetDefaultValue(something, NameOf(something.WithDefault)) Then
            Console.WriteLine($"{NameOf(something.WithDefault)} reset to ""{something.WithDefault}""")
        Else
            Console.WriteLine($"No default value for {NameOf(something.WithDefault)}")
        End If

        If TrySetDefaultValue(something, NameOf(something.WithoutDefault)) Then
            Console.WriteLine($"{NameOf(something.WithoutDefault)} reset to ""{something.WithoutDefault}""")
        Else
            Console.WriteLine($"No default value for {NameOf(something.WithoutDefault)}")
        End If
    End Sub

    Public Function TryGetDefaultValue([object] As Object, propertyName As String, ByRef value As Object) As Boolean
        Dim attribute = [object].GetType().GetProperty(propertyName).GetCustomAttribute(Of DefaultValueAttribute)()

        If attribute Is Nothing Then
            Return False
        End If

        value = attribute.Value

        Return True
    End Function

    Public Function TrySetDefaultValue([object] As Object, propertyName As String) As Boolean
        Dim [property] = [object].GetType().GetProperty(propertyName)
        Dim attribute = [property].GetCustomAttribute(Of DefaultValueAttribute)()

        If attribute Is Nothing Then
            Return False
        End If

        Dim value = attribute.Value

        [property].SetValue([object], value)

        Return True
    End Function

End Module

Solution 2:

There's no out-of-the-box way to somehow revert a property to its (custom) initial value. Once it's changed, it's over; the original value is lost.

Assuming the property belongs to a class (and that it doesn't get modified in the constructor), you could retrieve the value by creating a temporary instance of the class. For example:

Class SomeClass
    Public Property Name As String = "default_name"

    Sub InitializeFields()
        Name = String.Empty
        '
        '
        '
        Name = New SomeClass().Name
    End Sub
End Class

However, that's not very robust and could get ugly really fast. The way I would do this is by storing the default value in a constant:

Private Const DefaultName As String = "default_name"

Public Property Name As String = DefaultName

Sub InitializeFields()
    Name = String.Empty
    '
    '
    '
    Name = DefaultName
End Sub

And then you can do that for each property that you need to later access its original value.