C#: 从另一个类访问枚举

17

我知道我可以直接在命名空间中声明一个enum,这样每个人都可以在相同的命名空间中访问它。

但是我能否在一个类中声明它以便从其他类中访问:

public class Class1
{
    public enum Mode { Selected, New }  
}

public class Class2
{
    var class1 = new ();
    // Set the Mode
    class1.Mode = Mode.Selected;
}

是否可能在不声明命名空间的情况下使用 enums


真的不太明白你的意思...你只能从对象中访问在类内定义的类,就像你现在所做的一样,那么问题出在哪里呢? - Machinarius
你到底为什么要避免使用命名空间限定符?另外,“类的命名空间区域”并不是很清晰。 - 3Dave
1
在我看来,你应该将枚举定义在它自己的文件中。这样你就不需要引用嵌套类了。 - froeschli
@froeschli 我同意你评论的精神,但是你不必将枚举放在单独的文件中以防止它嵌套在类内部。 - 3Dave
@David Lively 我通过学习Java来学习面向对象编程。我猜这种将每个类/枚举放在单独文件中的方式有点让人难以忘怀。 - froeschli
@froeschil 通常最好的做法是将它们分别保存在不同的文件中,但也有例外。Java并不是唯一强制执行此规则的语言。 - 3Dave
8个回答

23

你可以在类外声明枚举:

namespace MyNamespace
{
    public enum MyEnum
    {
        Entry1,
        Entry2,
    }
}

然后在需要使用的地方添加 using MyNamespace;


1
OP说:“这是否有可能不使用命名空间区域来实现?” - cdhowie
@cdhowie:我对问题中的某些措辞感到困惑,所以我认为她试图避免完全限定类名的需要。你和我给出的答案基本上完全展示了枚举如何声明,因此无论如何都应该回答这个问题 :-) - Mark Avenius
我明白了,是的,那是一个可能的解释。措辞确实不清楚。 :) - cdhowie
哇,这是我找到的最简单的解决方案! - Chandraprakash

10
亚伦的回答非常好,但我认为有一种更好的方法来做到这一点:
public static class class1
{
    public void Run()
    {
        class2.Mode mode = class2.Mode.Selected;

        if (mode == class2.Mode.Selected)
        {
            // Do something crazy here...
        }
    }
}

public static class class2
{
    public enum Mode
    { 
        Selected, 
        New
    } 
}

没有必要过分复杂化这个问题。这是一个简单的任务。

祝一切顺利

克里斯。


3
当我使用被接受的解决方案时,出现了“接口不能声明类型”的错误,不过它还是很好地运作了! - patti_jane

5

是的:

class2.Mode = class2.Mode.Selected

但请注意,您不能定义一个嵌套类型,它与外部类的成员名称相同,因此此代码将无法编译。枚举或属性需要命名为其他名称。您的类名和变量名也存在冲突,这使得问题更加复杂。

为了使答案更加通用,如果您有以下代码:

public class Foo
{
    public SomeEnum SomeProperty { get; set; }

    public enum SomeEnum {
        Hello, World
    }
}

那么这段代码将会给属性分配一个枚举值:
Foo foo = new Foo();
foo.SomeProperty = Foo.SomeEnum.Hello;

1
当我输入class2.时,Intellisense中没有出现Mode枚举,所以似乎它不起作用。正如我所描述的,我想在实例上设置Mode,而不是通过classname.Mode。 - Elisabeth
@Lisa:那是因为你把变量命名为了与类相同的名称。符号重叠了,编译器就会认为你指的是这个变量。你需要更改变量名或类名。在更改其中一个之后,请查看我的额外示例代码以获取正确的语法。 - cdhowie
@Elisabeth 我曾经遇到过同样的问题。我最终找到的解释非常简单:枚举是类的一部分,而不是类实例的一部分。正如你在上面评论的那样,使用属性是最好的解决方案。 - jibbs

4
如果您试图按照下述方式操作,则此方法将无法正常工作...
    public class MyClass1
    {
        private enum Mode { New, Selected };
        public Mode ModeProperty { get; set; }
    }

    public class MyClass2
    {
        public MyClass2()
        {
            var myClass1 = new MyClass1();

            //this will not work due to protection level
            myClass1.ModeProperty = MyClass1.Mode.
        }
    }

您可以尝试以下方法,这些方法将起作用...
    public interface IEnums
    {
        public enum Mode { New, Selected };
    }

    public class MyClass1
    {
        public IEnums.Mode ModeProperty { get; set; }
    }

    public class MyClass2
    {
        public MyClass2()
        {
            var myClass1 = new MyClass1();

            //this will work
            myClass1.ModeProperty = IEnums.Mode.New;
        }
    }

@Lisa,我编辑了答案,使其更符合我认为你想要做的事情...如果不是的话...那么另一个答案就在历史记录中... :) - Aaron McIver
1
我也是,除了Idan Shechter的评论“使用此代码时,接口无法声明类型”。 - fletchsod
1
@AaronMcIver 接口不能包含枚举。 - p__d
即使这是被接受的答案,但这是不必要的。根据您的第一个示例,您可以将其设置为公共并且它会起作用,否则您可以在类外声明枚举,有效地在同一命名空间中声明,并且它也会起作用。我对接口感到好奇,为什么要在接口上声明? - Barreto

1

我最终通过将其更改为命名空间访问器来解决我的问题,利用Intellisense找到了它。我以为枚举在类中,而不仅仅是在命名空间中。如果它在类中,我建议将其移出类。

namespace ABC.XYZ.Contracts
{
  public class ChangeOrder : BaseEntity, IAuditable
  {
     ...
  }

  public enum ContractorSignatureType
  {
    A,
    B,
    V
  }
}
< p > ContractorSignatureType = Contracts.ContractorSignatureType.B,

承包商签名类型=合同.承包商签名类型.B,

0

这个问题不是很清楚,每个答案似乎都有主观性,所以这是我的看法:

  • 当我们有一个需要唯一enum的类时,我们可以在同一个类中声明它,它将在所有人实例中都可访问。
namespace MyApp.Models
{
   public class Person
   {
      public AgeGroup ageGroup;

      public enum AgeGroup { Baby, Child, Teen, Adult, Senior}
   }
}

声明:

using MyApp.Models;
(...)
Person p = new();
p.ageGroup = Person.AgeGroup.Baby;

但您可以看到,使用Person.AgeGroup.Baby有点冗长。

  • 或者,我们可以在与要使用的类相同的命名空间中声明enum,如果它是唯一的,则最好放在同一个文件中的类下方,但这完全是可选的。

该方法使枚举可以在其宣布的命名空间中随处使用。

namespace MyApp.Models
{
    public class Person
    {
        public AgeGroup ageGroup;
    }

    public enum AgeGroup { Baby, Child, Teen, Adult, Senior}
}

声明:

using MyApp.Models;
(...)
Person p = new();
p.ageGroup = AgeGroup.Baby;

请注意,命名空间与Person类相同,因此不需要额外的命名空间。
当在您的项目(s)上“全面使用”枚举时,可以在更可访问的命名空间中声明它,例如您的主要项目命名空间:
namespace MyApp
{
    //this could be your "App.cs" file with the enum declared after the class
    //or just a new "SomeEnums.cs" file
    public enum Mode {A, B}
}

声明:

namespace MyApp.ViewModels
{
    public class Test
    {
        Mode mode = Mode.A;
    }
}

请注意,在上一个示例中,我声明了MyApp命名空间,但我在子/嵌套命名空间MyApp.ViewModels中使用了它。
或者将枚举声明在专门用于辅助程序的命名空间中,我使用此命名空间来声明扩展方法、全局枚举和任何其他静态辅助程序。
namespace MyApp.Helpers
{
    public enum Mode { A, B}
}

声明:

using MyApp.Helpers;
namespace MyApp
{
    public class Test
    {
        Mode mode = Mode.A;
    }
}

0
//by using this you can access the value of enum.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace @enum
{
    class temp
    {
       public enum names
        {
            mohitt,
            keval,
           Harshal,
           nikk
        }

    }
    class Program
    {

        static void Main(string[] args)
        {

            Console.WriteLine(temp.names.nikk);
            Console.ReadKey();

        }
    }
}

-1
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace @enum
    {
        class temp
        {
           public enum names
            {
                mohitt,
                keval,
               Harshal,
               nikk
            }

        }


        class Program
        {

            static void Main(string[] args)
            {

                Console.WriteLine((int)temp.names.nikk);
                Console.ReadKey();

            }
        }
    }

你应该解释这段代码是如何回答问题的以及为什么。只有发布未经注释的代码是没有帮助的。 - Irreducible
这似乎是一个不好的做法,将命名空间称为“enum”。并且你可以在不使用“temp”类的情况下声明它。 - Barreto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接