C# 类修饰符

C# 类修饰符,c#,vb.net,class,C#,Vb.net,Class,我从来没有主动学习过正确的类修饰语,因为它一直是一个“很好拥有”而不是“需要拥有” 让我恼火的是,我能以新人的身份做dimf.FavoriteFoodsList 我应该使用哪个类修饰符,以便我的Person类可以使用FavoriteFoodList,但Person之外的任何东西都不能实例化FavoriteFoodList Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Ha

我从来没有主动学习过正确的类修饰语,因为它一直是一个“很好拥有”而不是“需要拥有”

让我恼火的是,我能以新人的身份做
dimf.FavoriteFoodsList

我应该使用哪个类修饰符,以便我的Person类可以使用FavoriteFoodList,但Person之外的任何东西都不能实例化FavoriteFoodList

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

编辑3:删除了尝试将以下模式应用于私有/受保护成员的此答案的早期版本:

为了说明这将如何跨程序集边界工作,下面是一个示例:

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();
}
公共类人物
{
公共抽象类FavoriteFoodList:列表
{
//内部构造函数阻止其他程序集中的类型继承
内部FavoriteFoodList(){}
}
私有类FFL2:FavoriteFoodList
{
}
public FavoriteFoodList FavoriteFoods=new FFL2();
}

免责声明,这只是说明可访问性问题的草图;该字段应为属性等。

编辑3:删除了试图将以下模式应用于私有/受保护成员的此答案的早期版本:

为了说明这将如何跨程序集边界工作,下面是一个示例:

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();
}
公共类人物
{
公共抽象类FavoriteFoodList:列表
{
//内部构造函数阻止其他程序集中的类型继承
内部FavoriteFoodList(){}
}
私有类FFL2:FavoriteFoodList
{
}
public FavoriteFoodList FavoriteFoods=new FFL2();
}

免责声明,这只是说明可访问性问题的草图;字段应该是属性等。我建议您为类定义一个公共接口,然后将实现标记为私有

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

我建议您为类定义一个公共接口,然后将实现标记为私有

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

没有任何类修饰符或可访问性修饰符可以让您在一个程序集中完成此操作。正如另一位回答者所说,带有私有实现类的接口可能是最好的解决方案


但是,如果您正在编写类库,则可以将FavoriteFoodList的所有构造函数声明为
内部
我认为是VB中的Friend
),这将阻止其他程序集构造它们自己的FavoriteFoodList对象。

没有类修饰符或可访问性修饰符可以让您在一个程序集中完成此操作。正如另一位回答者所说,带有私有实现类的接口可能是最好的解决方案



但是,如果您正在编写类库,则可以将FavoriteFoodList的所有构造函数声明为
内部
我认为是VB中的Friend
),这将阻止其他程序集构造自己的FavoriteFoodList对象。

我尝试了您的建议,键入p时,我可以看到FavoriteFoods和FavoriteFoodList。我无法添加任何内容,确保您可以看到FavoriteFoodList。如果您希望能够使用该类,“基类”必须可见。@DontFretBrett感谢您的翻译;我已经将它添加到了答案中。@FrederikHeyses但是由于该类是抽象的,所以不能在类之外实例化它。我刚刚意识到,我们也需要防止外来者从类中继承;我不确定这是否可能。@DontFretBrett您无法向FavoriteFoodList实例添加任何内容,因为我忘记从
列表
派生FavoriteFoodList。但实现这一点的唯一方法是使用
内部
或使用接口。
internal
方法阻止来自其他程序集的代码实例化该类,但它不阻止同一程序集中的其他类型这样做。我尝试了你的建议,当我键入P时,我可以看到FavoriteFoods和FavoriteFoodList。我无法添加任何内容,确保您可以看到FavoriteFoodList。如果您希望能够使用该类,“基类”必须可见。@DontFretBrett感谢您的翻译;我已经将它添加到了答案中。@FrederikHeyses但是由于该类是抽象的,所以不能在类之外实例化它。我刚刚意识到,我们也需要防止外来者从类中继承;我不确定这是否可能。@DontFretBrett您无法向FavoriteFoodList实例添加任何内容,因为我忘记从
列表
派生FavoriteFoodList。但实现这一点的唯一方法是使用
内部
或使用接口。
internal
方法阻止来自其他程序集的代码实例化该类,但它不会阻止同一程序集中的其他类型这样做。谢谢先生。这就成功了!!我会尽快接受答案。上面说我还要再等3分钟实际上,这和phoog的回答有些相同。您也不能从phoog的解决方案中实例化FavoriteFoodList。但是,我觉得这个更好一些,因为接口是在Person类之外定义的,比如在phoog的答案中,有一个嵌套的公共类,它不是“友好的”imho。在phoogs的答案中,我不能将食物添加到列表中。我尝试了P.FavoriteFoods.Add,没有可用的Add方法*编辑,我猜是因为我没有继承列表?那是因为他忘了从列表继承FavoriteFoodList抽象类-我编辑了他的C#代码示例。@FrederikHeyses我同意嵌套的公共类不是那么友好;我主要是想解决原来问题的模式,而不是想找出最好的解决办法。谢谢你,先生。这就成功了!!我会尽快接受答案。上面说我还要再等3分钟实际上,这和phoog的回答有些相同。您也不能从phoog的解决方案中实例化FavoriteFoodList。然而,我发现这一个更好一点,因为接口