DontFretBrett
DontFretBrett

Reputation: 1165

Class Modifiers

I've never taken the initiative to learn the correct class modifier since it has always been a "nice to have" but not a "need to have".

It annoys me that I can do Dim F as New Person.FavoriteFoodsList.

Which class modifier do I use so that my Person class can utilize the FavoriteFoodsList but nothing outside of Person can instantiate the FavoriteFoodsList?

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim P As New Person
    P.FavoriteFoods.Add("Pizza")
    Dim F As New Person.FavoriteFoodsList 'How do I prevent this
End Sub
Public Class Person
    Public FavoriteFoods As New FavoriteFoodsList
    Public Class FavoriteFoodsList
        Inherits Collections.Generic.List(Of String)
    End Class
End Class

Upvotes: 2

Views: 312

Answers (3)

phoog
phoog

Reputation: 43056

EDIT 3: removed earlier version of this answer that tried to apply the pattern below to private/protected members:

To illustrate how this would work across assembly boundaries, here's an example:

public class Person
{
    public abstract class FavoriteFoodsList : List<string>
    {
        //internal constructor prevents types in other assemblies from inheriting
        internal FavoriteFoodsList(){}
    }
    private class FFL2 : FavoriteFoodsList
    {
    }
    public FavoriteFoodsList FavoriteFoods = new FFL2();
}

Disclaimer, this is just a sketch to illustrate the accessibility issues; the field should be a property, etc.

Upvotes: 2

David Yaw
David Yaw

Reputation: 27864

There's no class modifier or accessibility modifier that will let you accomplish this within one assembly. An interface with a private implementation class, as the other answerer said, is probably the best solution.

However, if you're writing a class library, you can declare all of FavoriteFoodsList's constructors as internal (Friend in VB, I think), and that will prevent other assemblies from constructing their own FavoriteFoodsList objects.

Upvotes: 0

ChaosPandion
ChaosPandion

Reputation: 78282

I recommend you define a public interface for your class then mark the implementation as private.

Public Interface IFavoriteFoodsList
    Inherits Collections.Generic.IList(Of String)
    ' Define other public api methods'
End Interface

Public Class Person
    Public FavoriteFoods As IFavoriteFoodsList = New FavoriteFoodsList
    Private Class FavoriteFoodsList
        Inherits Collections.Generic.List(Of String)
        Implements IFavoriteFoodsList
    End Class
End Class

Upvotes: 2

Related Questions