C# 在C中不可能使用受保护的枚举#

C# 在C中不可能使用受保护的枚举#,c#,language-features,C#,Language Features,我只是想了解为什么我不能在C#上创建受保护的枚举 编译器拒绝接受这一点 有人知道为什么会这样吗?如果是嵌套类型,您可以使用protectedaccess修饰符创建enum。直接在命名空间中创建的类型只能采用公共和内部访问修饰符。直接在命名空间中创建私有、受保护或受保护的内部类型没有意义,因为您不能在任何地方使用它(因为您不能从命名空间继承或在其中声明方法).您可以拥有嵌套在另一个类型中的受保护类型,该类型包括枚举: public class Outer { protected enum

我只是想了解为什么我不能在C#上创建受保护的枚举

编译器拒绝接受这一点


有人知道为什么会这样吗?

如果是嵌套类型,您可以使用
protected
access修饰符创建
enum
。直接在
命名空间
中创建的类型只能采用
公共
内部
访问修饰符。直接在
命名空间中创建
私有
受保护
受保护的内部
类型没有意义,因为您不能在任何地方使用它(因为您不能从命名空间继承或在其中声明方法).

您可以拥有嵌套在另一个类型中的受保护类型,该类型包括枚举:

public class Outer
{
    protected enum NestedEnum { Foo, Bar, Baz };
}
但是,将非嵌套类型设为受保护是没有意义的——受保护的修饰符是关于从派生类型中授予对成员的访问权;由于顶级类型只是名称空间的一个成员,而不是另一个类型,因此没有可以从中派生的类型来获得额外的访问权限


您能描述一下您实际想要实现的目标吗?然后我们可以尝试找出最合适的可见性是什么?

您确定您没有在类之外声明吗

在类内部,它可以正常工作,但不能声明受保护的成员,因为没有可派生的内容。如果它是在类中定义的,则可以从中派生并访问它


类定义之外的受保护枚举将无法从任何位置访问

嵌套枚举可能受到“保护”

class Test
    {
        protected enum MyEnum
        {
            type1,
            type2
        }
    }

受保护的
修饰符仅在类声明的上下文中有意义-它确定标记为受保护的项可供类及其派生类访问,但不在类之外

如果枚举是类的嵌套枚举,则可以将其声明为受保护

但是,如果它是顶级枚举,则可以是公共枚举或内部枚举。当然,公共意味着大会内外的每个人都可以看到它。内部表示它仅在部件内可见也许你要找的是内部的。

编辑:枚举值在C#中不可继承-允许此操作的唯一目的是能够向枚举添加其他值。虽然枚举无法实现,但我们可以使用类似于Java的方法来实现这一点:

public class BaseEnum 
{
    private readonly int m_Value;

    protected BaseEnum( int val ) { m_Value = val; }

    public static readonly BaseEnum First  = new BaseEnum(1);
    public static readonly BaseEnum Second = new BaseEnum(2);
    public static readonly BaseEnum Third  = new BaseEnum(3);
}

public class DerivedEnum : BaseEnum
{
    protected DerivedEnum( int val ) : base( val ) { }

    public static readonly DerivedEnum Fourth = new DerivedEnum(4);
    public static readonly DerivedEnum Fifth  = new DerivedEnum(5);
}

谢谢-但是为什么呢?为什么一个类可以被保护而一个枚举不能(在顶层)我想创建一个可以被子类扩展的枚举不能在C#/.NET中扩展-它们是从System.ValueType派生的,因此,与结构类似,你不能从它们继承。@ChloeRadshaw:两件事:首先,枚举是不可继承的-只有类是可继承的。在C#中不能从另一个枚举派生一个枚举。第二,你不能在顶层将任何东西标记为受保护的,即使是类。受保护修饰符仅在类中使用,以指示该类的成员可由类和派生类访问,但不可由任何其他代码访问。在名称空间级别,您只能将内容标记为
public
internal
——您只是说明类型在程序集外部是否可见。@LBushkin:您确定吗?这编译了很好的名称空间控制台应用程序1{受保护的类CsvReader{}}确实内部可以工作,但我不明白为什么不能在naespace级别通过“extend”扩展枚举您的意思是创建派生枚举吗?这是不可能的,因为枚举是一种特殊的值类型,不能继承值类型。@ChloeRadshaw:枚举不可继承-不能从一个枚举派生另一个枚举。它们只是为一组值提供名称的一种方便方式。+1“typsafe枚举”的一个有趣示例:好奇在现实世界中您会使用这种“奇美拉”在什么情况下使用?我真的很喜欢这种方法,遗憾的是,这种方法消除了枚举的
常量,从而使它无法用于
开关
语句。你能发布你的代码吗。我在VS2008上检查了它,它成功了。