天道酬勤,学无止境

如何使用流利的NHibernate将枚举映射为int值?(How do you map an enum as an int value with fluent NHibernate?)

问题

问题确实如此,默认是将其映射为string但我需要将其映射为int

我目前正在使用PersistenceModel来设置我的约定,如果有什么不同的话。 提前致谢。

更新发现从主干上获取最新版本的代码解决了我的麻烦。

回答1

定义此约定的方式有时是在以前更改的,现在是:

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}
回答2

因此,如上所述,从后备箱中获取最新版本的Fluent NHibernate将我带到了我需要的地方。 具有最新代码的枚举的映射示例为:

Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));

自定义类型强制将其作为枚举的实例进行处理,而不是使用GenericEnumMapper<TEnum>

我实际上正在考虑提交一个修补程序,以便能够在保留字符串的枚举映射器和保留int的枚举映射器之间进行更改,因为这似乎应该可以设置为约定。


这突然出现在我最近的活动中,而Fluent NHibernate的较新版本中的内容进行了更改,以使其变得更加容易。

为了使所有枚举都映射为整数,您现在可以创建一个约定,如下所示:

public class EnumConvention : IUserTypeConvention
{
    public bool Accept(IProperty target)
    {
        return target.PropertyType.IsEnum;
    }

    public void Apply(IProperty target)
    {
        target.CustomTypeIs(target.PropertyType);
    }

    public bool Accept(Type type)
    {
        return type.IsEnum;
    }
}

然后,您的映射只需是:

Map(quote => quote.Status);

像这样将约定添加到Fluent NHibernate映射中;

Fluently.Configure(nHibConfig)
    .Mappings(mappingConfiguration =>
    {
        mappingConfiguration.FluentMappings
            .ConventionDiscovery.AddFromAssemblyOf<EnumConvention>();
    })
    ./* other configuration */
回答3

不要忘记可为空的枚举(例如ExampleEnum? ExampleProperty )! 它们需要单独检查。 这是通过新的FNH样式配置完成的:

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum ||
            (x.Property.PropertyType.IsGenericType && 
             x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) &&
             x.Property.PropertyType.GetGenericArguments()[0].IsEnum)
            );
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}
回答4

这就是我用int值映射枚举属性的方式:

Map(x => x.Status).CustomType(typeof(Int32));

为我工作!

回答5

对于那些将Fluent NHibernate与Automapping一起使用的人(可能还有一个IoC容器):

IUserTypeConvention就像上面的@ Julien的回答:https: IUserTypeConvention

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}

Fluent NHibernate Automapping配置可以这样配置:

    protected virtual ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
            .Database(SetupDatabase)
            .Mappings(mappingConfiguration =>
                {
                    mappingConfiguration.AutoMappings
                        .Add(CreateAutomappings);
                }
            ).BuildSessionFactory();
    }

    protected virtual IPersistenceConfigurer SetupDatabase()
    {
        return MsSqlConfiguration.MsSql2008.UseOuterJoin()
        .ConnectionString(x => 
             x.FromConnectionStringWithKey("AppDatabase")) // In Web.config
        .ShowSql();
    }

    protected static AutoPersistenceModel CreateAutomappings()
    {
        return AutoMap.AssemblyOf<ClassInAnAssemblyToBeMapped>(
            new EntityAutomapConfiguration())
            .Conventions.Setup(c =>
                {
                    // Other IUserTypeConvention classes here
                    c.Add<EnumConvention>();
                });
    }

*然后,可以轻松地在IoC中使用CreateSessionFactory ,例如Castle Windsor(使用PersistenceFacility和安装程序)。 *

    Kernel.Register(
        Component.For<ISessionFactory>()
            .UsingFactoryMethod(() => CreateSessionFactory()),
            Component.For<ISession>()
            .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
            .LifestylePerWebRequest() 
    );
回答6

您可以创建NHibernate IUserType ,并使用属性映射上的CustomTypeIs<T>()进行指定。

回答7

您应该在数据库表中将值保留为int / tinyint。 为了映射您的枚举,您需要正确指定映射。 请参见下面的映射和枚举示例,

映射类

public class TransactionMap : ClassMap Transaction
{
    public TransactionMap()
    {
        //Other mappings
        .....
        //Mapping for enum
        Map(x => x.Status, "Status").CustomType();

        Table("Transaction");
    }
}

枚举

public enum TransactionStatus
{
   Waiting = 1,
   Processed = 2,
   RolledBack = 3,
   Blocked = 4,
   Refunded = 5,
   AlreadyProcessed = 6,
}

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • LINQ相当于IEnumerable的foreach(LINQ equivalent of foreach for IEnumerable<T>)
    问题 我想在LINQ中执行以下操作,但是我不知道如何操作: IEnumerable<Item> items = GetItems(); items.ForEach(i => i.DoStuff()); 真正的语法是什么? 回答1 没有IEnumerable ForEach扩展; 仅用于List<T> 。 所以你可以做 items.ToList().ForEach(i => i.DoStuff()); 或者,编写您自己的ForEach扩展方法: public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action) { foreach(T item in enumeration) { action(item); } } 回答2 Fredrik提供了修复程序,但是可能值得考虑为什么它不在框架之内。 我认为LINQ查询运算符应该是无副作用的,并以合理的功能来看待世界。 显然,ForEach正好相反-纯粹基于副作用的构造。 这并不是说这是一件坏事,只是想想这个决定背后的哲学原因。 回答3 2012年7月17日更新:显然,从C#5.0版本开始,以下所述的foreach行为已更改,并且“在嵌套的lambda表达式中使用foreach迭代变量不再产生意外结果。” 此答案不适用于C#≥5.0。 @John
  • 从流畅的Nhibernate生成XML映射(Generate XML mappings from fluent Nhibernate)
    问题 如何在MappingIntegrationTests中的测试中生成xml映射文件 我需要手动检查流利的映射是否与旧项目中的映射相关。 回答1 您可以执行以下操作: config.Mappings(m => { m.FluentMappings.ExportTo("...file path here..."); m.HbmMappings.ExportTo("...file path here..."); m.AutoMappings.ExportTo("...file path here..."); { ); 我自己不喜欢如果我找到更好的方法(如果确实存在),我将更新答案。 看 http://blog.jagregory.com/2009/02/03/fluent-nhibernate-configuring-your-application/ 或者,如果损坏,请改为查看此内容 https://github.com/jagregory/fluent-nhibernate/wiki/数据库配置 回答2 您可以通过调用ExportTo()方法来生成XML映射。 例如: ISessionFactory sessionFactory = FluentNHibernate.Cfg.Fluently.Configure() .Database(FluentNHibernate.Cfg
  • 将JPA中的枚举映射为固定值?(Map enum in JPA with fixed values?)
    问题 我正在寻找使用JPA映射枚举的不同方法。 我特别想设置每个枚举项的整数值,并且只保存整数值。 @Entity @Table(name = "AUTHORITY_") public class Authority implements Serializable { public enum Right { READ(100), WRITE(200), EDITOR (300); private int value; Right(int value) { this.value = value; } public int getValue() { return value; } }; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "AUTHORITY_ID") private Long id; // the enum to map : private Right right; } 一个简单的解决方案是将枚举注释与EnumType.ORDINAL一起使用: @Column(name = "RIGHT") @Enumerated(EnumType.ORDINAL) private Right right; 但是在这种情况下,JPA映射枚举索引(0,1,2)而不是我想要的值(100,200,300)。
  • 如何从其String值查找Java枚举?(How can I lookup a Java enum from its String value?)
    问题 我想从其字符串值(或可能的任何其他值)中查找一个枚举。 我已经尝试了以下代码,但是在初始化程序中不允许使用静态代码。 有没有简单的方法? public enum Verbosity { BRIEF, NORMAL, FULL; private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>(); private Verbosity() { stringMap.put(this.toString(), this); } public static Verbosity getVerbosity(String key) { return stringMap.get(key); } }; 回答1 使用为每个枚举自动创建的valueOf方法。 Verbosity.valueOf("BRIEF") == Verbosity.BRIEF 对于任意值,请以: public static Verbosity findByAbbr(String abbr){ for(Verbosity v : values()){ if( v.abbr().equals(abbr)){ return v; } } return null; } 仅当您的探查器告诉您以后再继续执行Map实施。 我知道它会遍历所有值
  • 在现代C ++ 11 / C ++ 14 / C ++ 17和未来的C ++ 20中枚举为字符串(enum to string in modern C++11 / C++14 / C++17 and future C++20)
    问题 与所有其他类似问题相反,该问题与使用新的C ++功能有关。 2008 c有没有简单的方法可以将C ++枚举转换为字符串? 2008 c在C中将枚举类型的变量用作字符串的简单方法? 2008 c ++如何轻松将c ++枚举映射到字符串 2008 c ++使某些东西既是C标识符又是字符串? 2008 c ++是否有将C ++枚举转换为字符串的简单脚本? 2009 c ++如何在C ++中将枚举用作标志? 2011 c ++如何将枚举类型变量转换为字符串? 2011 c ++枚举到字符串C ++ 2011 c ++如何将枚举类型变量转换为字符串? 2012 c如何在c中将枚举名称转换为字符串 2013 c将C中有条件编译的枚举字符串化 阅读许多答案后,我尚未找到任何答案: 使用C ++ 11,C ++ 14或C ++ 17新功能的优雅方式或在Boost中可以立即使用的东西其他一些计划用于C ++ 20的东西 例子 一个例子通常比冗长的解释更好。 您可以在Coliru上编译并运行此代码段。 (也可以使用另一个以前的示例) #include <map> #include <iostream> struct MyClass { enum class MyEnum : char { AAA = -8, BBB = '8', CCC = AAA + BBB }; }; // Replace
  • 如何轻松地将C ++枚举映射到字符串(How to easily map c++ enums to strings)
    问题 我在使用的某些库头文件中有一堆枚举类型,并且我希望有一种将枚举值转换为用户字符串的方法,反之亦然。 RTTI不会为我做这件事,因为“用户字符串”需要比枚举更具可读性。 暴力解决方案将是一堆类似这样的功能,但是我觉得这有点像C。 enum MyEnum {VAL1, VAL2,VAL3}; String getStringFromEnum(MyEnum e) { switch e { case VAL1: return "Value 1"; case VAL2: return "Value 2"; case VAL1: return "Value 3"; default: throw Exception("Bad MyEnum"); } } 我有一种直觉,认为使用模板是一种优雅的解决方案,但是我还不能完全理解。 更新:感谢您的建议-我应该明确指出枚举是在第三方库标头中定义的,因此我不想更改它们的定义。 我现在的直觉是避免模板并执行以下操作: char * MyGetValue(int v, char *tmp); // implementation is trivial #define ENUM_MAP(type, strings) char * getStringValue(const type &T) \ { \ return MyGetValue((int)T
  • 如何从Java中的字符串值获取枚举值?(How to get an enum value from a string value in Java?)
    问题 说我有一个枚举 public enum Blah { A, B, C, D } 我想找到一个字符串的枚举值,例如"A"就是Blah.A 怎么可能做到这一点? Enum.valueOf()是我需要的方法吗? 如果是这样,我将如何使用它? 回答1 是的, Blah.valueOf("A")将给您Blah.A 请注意,名称必须完全匹配,包括大小写: Blah.valueOf("a")和Blah.valueOf("A ")都抛出IllegalArgumentException 。 静态方法valueOf()和values()在编译时创建,并且不会出现在源代码中。 但是,它们确实出现在Javadoc中。 例如,Dialog.ModalityType显示两个方法。 回答2 如果文本与枚举值不同,则另一种解决方案: public enum Blah { A("text1"), B("text2"), C("text3"), D("text4"); private String text; Blah(String text) { this.text = text; } public String getText() { return this.text; } public static Blah fromString(String text) { for (Blah b : Blah
  • NHibernate:如何XmlSerialize ISet ?(NHibernate: How do I XmlSerialize an ISet<T>?)
    问题 鉴于: 我正在尝试使用ASP.NET MVC创建REST API。 我在数据访问层中使用NHibernate。 问题: 我无法XmlSerialize ISet属性。 我收到如下错误: 无法序列化类型为Iesi.Collections.Generic.ISet`1 [[namespace]。[entity],[assembly],Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]],因为它是一个接口。 我会随意承认:我对NHibernate还是很陌生。 所以我不知道我的选择是什么。 我认为我需要使用套装而不是包,因为我的收藏品包含独特的物品。 当我将ISet属性转换为HashedTable属性(即一个具体的类)时,出现如下错误: 您必须在Iesi.Collections.Generic.HashedSet`1 [[namespace]。[entity],[assembly],Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]上实现默认访问器,因为它继承自ICollection。 我的问题: 我该怎么办才能纠正这种情况? 是否应该在所有实体类中实现默认访问器? 如果是这样,是否有建议的模式? 作为旁注,我尝试了Google搜索。
  • 一个“ for”循环来遍历Java中的一个枚举(A 'for' loop to iterate over an enum in Java)
    问题 我有一个Java的基本和中间方向enum : public enum Direction { NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST } 如何编写一个遍历每个enum值的for循环? 回答1 .values() 您可以在枚举上调用values()方法。 for (Direction dir : Direction.values()) { // do what you want } 此values()方法由编译器隐式声明。 因此它未在Enum文档上列出。 回答2 可以通过调用该类型的隐式public static T[] values()方法来获取枚举类型的所有常量: for (Direction d : Direction.values()) { System.out.println(d); } 回答3 您可以按照以下步骤进行操作: for (Direction direction : EnumSet.allOf(Direction.class)) { // do stuff } 回答4 溪流 Java 8之前的版本 for (Direction dir : Direction.values()) { System.out.println(dir); } Java 8
  • 流利的接口-方法链接(Fluent Interfaces - Method Chaining)
    问题 方法链接是我知道的建立流畅接口的唯一方法。 这是C#中的示例: John john = new JohnBuilder() .AddSmartCode("c#") .WithfluentInterface("Please") .ButHow("Dunno"); Assert.IsNotNull(john); [Test] public void Should_Assign_Due_Date_With_7DayTermsVia_Invoice_Builder() { DateTime now = DateTime.Now; IInvoice invoice = new InvoiceBuilder() .IssuedOn(now) .WithInvoiceNumber(40) .WithPaymentTerms(PaymentTerms.SevenDays) .Generate(); Assert.IsTrue(invoice.DateDue == now.AddDays(7)); } 那么其他人如何创建流畅的界面。 您如何创建它? 需要什么语言/平台/技术? 回答1 您可以使用任何版本的.NET或任何其他面向对象的语言来创建流畅的界面。 您需要做的就是创建一个对象,该对象的方法始终返回该对象本身。 例如在C#中: public class JohnBuilder {
  • 如何在Swift中使用索引和元素迭代循环(How to iterate a loop with index and element in Swift)
    问题 有没有我可以用来遍历数组并具有索引和元素的函数,例如Python的enumerate ? for index, element in enumerate(list): ... 回答1 是的。 从Swift 3.0开始,如果需要每个元素的索引及其值,则可以使用enumerated()方法遍历数组。 它返回由索引和数组中每个项目的值组成的对对的序列。 例如: for (index, element) in list.enumerated() { print("Item \(index): \(element)") } 在Swift 3.0之前和Swift 2.0之后,该函数称为enumerate() : for (index, element) in list.enumerate() { print("Item \(index): \(element)") } 在Swift 2.0之前, enumerate是一个全局函数。 for (index, element) in enumerate(list) { println("Item \(index): \(element)") } 回答2 Swift 5为Array提供了一种称为enumerated()的方法。 enumerated()具有以下声明: func enumerated() -> EnumeratedSequence
  • NHibernate如何查询一个IList 财产?(NHibernate How do I query against an IList<string> property?)
    问题 我正在尝试使用NHibernate对我的一个域类中的IList <string>属性进行查询。 这是一个简单的示例来演示: public class Demo { public Demo() { this.Tags = new List<string>(); } public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual IList<string> Tags { get; set; } } 映射如下: <class name="Demo"> <id name="Id" /> <property name="Name" /> <bag name="Tags"> <key column="DemoId"/> <element column="Tag" type="String" /> </bag> 而且我能够保存和检索就好了。 现在要查询我的域类的实例,其中Tags属性包含指定的值: var demos = this.session.CreateCriteria<Demo>() .CreateAlias("Tags", "t") .Add(Restrictions.Eq("t", "a")) .List<Demo>(); 错误结果
  • nHibernate映射到自定义类型(nHibernate mapping to custom types)
    问题 我有一个Oracle数据库,并且其中一个字段是日期范围字段。 它基本上只是以VARCHAR(40)的形式存储在数据库中,格式为YYYY / MM / DD-YYYY / MM / DD。 我想在nHibernate中将其映射到我这样创建的自定义类 public class DateTimeRange { public DateTimeRange(DateTime fromTime, DateTime toTime) { FromTime = fromTime; ToTime = toTime; } public override string ToString() { return String.Format("{0} to {1}", FromTime.ToString("HH:mm:ss"), ToTime.ToString("HH:mm:ss")); } public DateTime FromTime { get; set; } public DateTime ToTime { get; set; } } 我如何映射到这样的自定义类? 回答1 您需要实现自己的IUserType。 有关详细信息,请参见此博客文章。 如果博客消失,我还将在下面粘贴相关部分。 在NHibernate中,自定义映射类型是从IUserType或ICompositeUserType接口派生的类。
  • 与具有公共静态final字段的类相比,Java枚举有什么优势?(What's the advantage of a Java enum versus a class with public static final fields?)
    问题 我对C#非常熟悉,但是开始在Java中工作更多。 我希望了解到Java中的枚举基本上与C#中的枚举等效,但显然并非如此。 最初,我很高兴得知Java枚举可以包含多条数据,这似乎非常有利(http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)。 但是,从那时起,我发现了很多C#缺少的功能,例如能够轻松地为enum元素分配特定值的功能,以及因此无需花费大量精力即可将整数转换为enum的功能(即将整数值转换为匹配的Java枚举)。 所以我的问题是:与具有一堆公共静态final字段的类相比,Java枚举对Java枚举有什么好处吗? 还是只是提供更紧凑的语法? 编辑:让我更清楚。 与具有一堆相同类型的公共static final字段的类相比,Java枚举有什么好处? 例如,在第一个链接的“行星”示例中,与具有这些公共常量的类相比,枚举的优势是什么: public static final Planet MERCURY = new Planet(3.303e+23, 2.4397e6); public static final Planet VENUS = new Planet(4.869e+24, 6.0518e6); public static final Planet EARTH = new Planet(5
  • 如何在NHibernate中删除子对象?(How to delete child object in NHibernate?)
    问题 我有一个父对象,它与子对象的IList具有一对多的关系。 删除子对象的最佳方法是什么? 我不是要删除父母。 我的父对象包含一个子对象的IList。 这是一对多关系的映射: <bag name="Tiers" cascade="all"> <key column="mismatch_id_no" /> <one-to-many class="TGR_BL.PromoTier,TGR_BL"/> </bag> 如果我尝试使用clear()从集合中删除所有对象,然后调用SaveOrUpdate(),则会出现此异常: System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 如果我尝试分别删除子对象,然后将它们从父对象中删除,则会出现异常: deleted object would be re-saved by cascade 这是我第一次处理在NHibernate中删除子对象。 我究竟做错了什么? 编辑:只是为了澄清-我不是要删除父对象,只是子对象。 我与父母建立了一对多的关系。 我还需要在子对象映射上创建多对一关系吗? 回答1 之所以会出现第一个错误,是因为从集合中删除项目时,NHibernate的默认操作模式是简单地断开关联。 在数据库中
  • 我如何将int枚举为枚举?(How can I cast int to enum?)
    问题 如何将int enum为C#中的enum ? 回答1 从int: YourEnum foo = (YourEnum)yourInt; 从字符串: YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString); // The foo.ToString().Contains(",") check is necessary for enumerations marked with an [Flags] attribute if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(",")) { throw new InvalidOperationException($"{yourString} is not an underlying value of the YourEnum enumeration.") } 更新: 从数字上你也可以 YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt); 回答2 只需将其转换为: MyEnum e = (MyEnum)3; 您可以使用Enum.IsDefined检查它是否在范围内: if (Enum
  • 什么是枚举,为什么有用?(What are enums and why are they useful?)
    问题 今天,我浏览了该站点上的一些问题,发现提到了一个单例模式中使用的enum ,该enum声称这种解决方案具有线程安全性。 我从未使用过enum并且我使用Java编程已经有两年多了。 显然,他们改变了很多。 现在,他们甚至在自己内部对OOP进行了全面的支持。 现在为什么在日常编程中使用枚举?为什么?为什么? 回答1 当变量(尤其是方法参数)只能从一小部分可能的值中取出一个时,应始终使用枚举。 例如类型常量(合同状态:“永久”,“临时”,“学徒”)或标志(“立即执行”,“推迟执行”)。 如果使用枚举而不是整数(或字符串代码),则将增加编译时检查并避免错误传入无效常量,并记录哪些值是合法使用的。 顺便说一句,枚举的过度使用可能意味着您的方法做的太多(通常最好有几个单独的方法,而不是一个带有几个修改其功能的标志的方法),但是如果您必须使用标志或键入代码,则枚举是要走的路。 例如,哪个更好? /** Counts number of foobangs. * @param type Type of foobangs to count. Can be 1=green foobangs, * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types. * @return number of foobangs of type */ public int
  • IndexOutOfRangeException在NHibernate的深处(IndexOutOfRangeException Deep in the bowels of NHibernate)
    问题 我有以下映射: public class SecurityMap : ClassMap<Security> { public SecurityMap() { Table("Security"); CompositeId().KeyProperty(k => k.Id, "SecurityId").KeyProperty(k => k.EndDate); Map(x => x.LastUpdateUser); References(x => x.Company).Columns("CompanyId", "EndDate"); References(x => x.PrimaryListing).Columns("PrimaryListingId", "EndDate"); } } public class ListingMap : ClassMap<Listing> { public ListingMap() { Table("Listing"); CompositeId().KeyProperty(k => k.Id, "ListingID").KeyProperty(k => k.EndDate); References(x => x.Security).Columns("SecurityId","EndDate"); } } public class CompanyMap
  • 如何在编译时确保枚举开关的完整性?(How to ensure completeness in an enum switch at compile time?)
    问题 我有几个测试enum switch语句。 所有enum值必须在case语句中的switch语句中处理。 在代码重构期间,可能会发生enum缩小和增长的情况。 当enum缩小时,编译器将引发错误。 但是,如果enum增加,则不会引发任何错误。 匹配状态被遗忘并产生运行时错误。 我想将此错误从运行时移到编译时。 从理论上讲,应该可以在编译时检测到缺少的enum案例。 有什么办法可以做到这一点? 该问题已经存在:“如何检测已将新值添加到枚举,并且未在开关中处理”,但它仅包含与Eclipse相关的解决方案,不包含答案。 回答1 另一种解决方案使用功能性方法。 您只需要根据下一个模板声明枚举类: public enum Direction { UNKNOWN, FORWARD, BACKWARD; public interface SwitchResult { public void UNKNOWN(); public void FORWARD(); public void BACKWARD(); } public void switchValue(SwitchResult result) { switch (this) { case UNKNOWN: result.UNKNOWN(); break; case FORWARD: result.FORWARD(); break
  • 如何将枚举类型变量转换为字符串?(How to convert an enum type variable to a string?)
    问题 如何使printf显示枚举类型的变量的值? 例如: typedef enum {Linux, Apple, Windows} OS_type; OS_type myOS = Linux; 我需要的是 printenum(OS_type, "My OS is %s", myOS); 其中必须显示字符串“ Linux”,而不是整数。 我想,首先,我必须创建一个值索引的字符串数组。 但是我不知道这是否是最美丽的方式。 有可能吗? 回答1 确实没有做到这一点的美丽方法。 只需设置一个由枚举索引的字符串数组即可。 如果执行大量输出,则可以定义一个操作符<<,该操作符带有一个枚举参数并为您查找。 回答2 当然,天真的解决方案是为每个枚举编写一个函数,以执行到字符串的转换: enum OS_type { Linux, Apple, Windows }; inline const char* ToString(OS_type v) { switch (v) { case Linux: return "Linux"; case Apple: return "Apple"; case Windows: return "Windows"; default: return "[Unknown OS_type]"; } } 但是,这是维护灾难。 借助可以与C和C ++代码一起使用的Boost