Question: So, I wrote two classes for a practice project I'm working on, and there's something I've been thinking about for a while now.

Here are the classes:

Card:

```
Public Class Card

Dim Suit As String
Dim Name As Object
Dim Value As Byte

Public Function GetSuit()
    Return Suit
End Function

Public Function GetName()
    Return Name
End Function

Public Function GetValue()
    Return Value
End Function

Public Sub SetSuit(ByVal a)
    Suit= a
End Sub

Public Sub SetName(ByVal a)
    Name= a
End Sub

Public Sub SetValue(ByVal a)
    Value= a
End Sub

End Class

```

And the procedure called by the constructor of the Deck class that populates the deck upon initialization:

```
Private Sub Populate(ByVal Name As Object, ByVal Suit As String, ByRef Deck As List(Of Karta))

    Dim NewCard As Card = New Card

    New.SetSuit(Suit)

    Select Case Name
        Case 1
            New.SetName("Ace")
            New.SetValue(11)
        Case 3
            New.SetName(Name)
            New.SetValue(10)
        Case 11
            New.SetName(Name)
            New.SetValue(2)
        Case 12
            New.SetName(Name)
            New.SetValue(3)
        Case 13
            New.SetName(Name)
            New.SetValue(4)
        Case Else
            New.SetName(Name)
    End Select

    Deck.Add(New)

End Sub

```

What I've been wondering is, is there any way for me to make the Setter procedures in the Card class private and have the Population procedure still be able to do it's job?

Having those setter procedures in the Card class kinda defeats the purpose of making the variables themselves private.

Answer: 
You could set the getter/setter methods to Private and allow creation of card objects via a Constructor. This would make the properties "settable" on initialisation from other classes, but not editable once the object has been created. This seems to make sense for a 'card' object, where the value and name of the card is unlikely to change.

Example constructor for the Card class:

```
Public Sub New(_suit As String, _name As Object, _value as Byte)
    Suit = _suit
    Name = _name 
    Value = _value 
End Sub

```
You should absolutely be using properties. The whole point of properties is that they behave like fields from the outside, i.e. you set them directly in the same way you do fields, but they behave like methods from the inside, i.e. you can add extra code like calculations, validation and raising of events. You can declare private backing fields yourself and fully implement the property, e.g.

```
Public Class Card

    Private _suit As String

    Public Property Suit As String
        Get
            Return _suit
        End Get
        Set
            _suit = value
        End Set
    End Property

End Class

```

As you can see, the property definition incorporates Get and Set methods. When you compile, that `Suit` property actually becomes a `get_Suit` method and a `set_Suit` method.

If you're not going to do anything other than get and set the backing field though, you can use an auto-property:

```
Public Class Card

    Public Property Suit As String

End Class

```

This compiles to exactly the same code as the first snippet, private backing field and all, but is much easier for you to write.