为什么对象实例中的枚举具有静态上下文?

时间:2015-03-25 09:01:58

标签: c# enums

我有以下课程:

public class HandleResourceReferencesParams
{
    public Factory Factory { get; set; }
    public DataObject Resource { get; set; }
    public HandleAction Action { get; set; }

    public enum HandleAction
    {
        Activate,
        Disable,
        Terminate
    }
}

以下代码中使用了以下内容:

var parameters = new HandleResourceReferencesParams();
parameters.Factory = context.Factory;
parameters.Resource = resource;
parameters.Action = parameters.HandleAction.Terminate; // Does not compile
HandleResourceReferences(parameters);

使用parameters.HandleAction,我收到编译错误:

  

无法访问静态枚举' HandleAction'在非静态环境中

明显没有声明枚举'静态'。为什么它从对象实例引用时有静态上下文(非静态)?

修改 我已经找到了Tim提到的解决方案(顺便提一下)。我只是想了解为什么我会收到此错误。

3 个答案:

答案 0 :(得分:4)

错误信息很不幸,但不能不能 它...您尝试访问某个类型的成员,而不是该类型的实例的成员,但您正在这样做"通过"一个实例。

基本上,这与代码编译失败的原因相同:

Thread t = new Thread(...);
t.Start();
t.Sleep(1000); // Nope, Sleep is a static method

所有嵌套类型都是有效的静态成员,因为您不能拥有特定于包含类型实例的类型。

从C#规范,第10.3.7节(强调我的):

  

当字段,方法,属性,事件,运算符或构造函数声明包含static修饰符时,它会声明一个静态成员。 此外,常量或类型声明隐式声明静态成员。

所以枚举是该类型的静态成员,尽管没有static修饰符。

答案 1 :(得分:3)

使用

parameters.Action = HandleResourceReferencesParams.HandleAction.Terminate; 

您为实例属性分配枚举,但​​枚举本身就像一个静态变量。

因此,您无法通过声明它的外部类的实例调用枚举。如果您尝试通过其类的实例使用静态字段,则类似于编译器错误:

public class FooClass
{
    public static string Foo = "Foo";
    public string FooProp { get; set; }
}

您无法通过实例访问静态字段FooClass.Foo

var foo = new FooClass();
foo.FooProp = foo.Foo; // does not compile either, you have to use FooClass.Foo

enum由一组命名常量组成,const隐含static

为什么编译器不允许我使用实例?因为它试图阻止你明显的粗心错误。您不需要实例,所以不要使用它。

答案 2 :(得分:0)

  

我找到了如何编译,我问的原因是它没有编译我是怎么做的

HandleAction.Terminate是枚举的值。 它的值与HandleResourceReferencesParams的实例没有关联,但是它的类型嵌套在对象HandleResourceReferencesParams中。

它是枚举的定义,而不是像实例化的属性或变量那样的成员。

嵌套定义(枚举,结构或类)的唯一特性是其父类的特定权限。