C# - 使用枚举作为唯一标识符的替代方法

时间:2013-09-27 18:50:18

标签: c# enums anti-patterns

我认为这是一种常见的情况,但用谷歌搜索找不到满意的答案。

问题:是否有一种模式可以解决从数据库中查找枚举值的问题?

情况:我的任务是重构Winforms应用程序,该应用程序的内存使用率非常高。罪魁祸首是“常量”项目 - 基本上是一堆枚举类。它们的目的是复制数据库查找表值(参见下面的示例)。

    public enum Status
    {
        None = -1,
        Active = 0,
        Completed = 1,
        Review = 2,
        Proceed = 3
    }

每次应用加载时,所有这些枚举都必须加载到内存中。是否有一种模式允许您解决此问题,但也不会使用查询终止数据库?

1 个答案:

答案 0 :(得分:1)

虽然很难相信enum的程序集确实可以成为高内存使用的主要来源(我甚至不想想那个程序集的SIZE),但是一些可能的解决方案会流入记:

  1. enum以外的内容探索内存贪婪的enum程序集。是的,这是一个微不足道的建议,但它毕竟是最合理的。
  2. enum程序集与主项目合并。虽然enum本身几乎不占用内存,但相关的超大装配本身就可以完全(例如,由于大量使用属性)。
  3. 使用一堆不一定static的类实现必要的值,这些类充满了一堆public static readonly int字段(不是const s)。如果所有这些都被调用至少一次,几乎不会减少内存使用量,但可能会导致一些减少,具体取决于用户的操作。但是,那些讨厌的int更难以解释enum s。
  4. 使用缓存的singleton-ish模式实现必要的值(也许这个模式有一个名称,但我不熟悉它)。虽然在每个实例的基础上内存显然更难,但它允许(虽然取决于GC)生活并根据使用情况扼杀它。基本上,它应该像

    internal abstract class ErzatsEnumBase {
        protected static readonly ObjectCache Cache = MemoryCache.Default;
        protected ErzatsEnumBase ( string CacheKey, CacheItemPolicy CachePolicy ) {
            Cache.Add ( CacheKey, this, CachePolicy, null );
        }
    }
    public sealed class ErzatsEnum: ErzatsEnumBase {
        private static CacheItemPolicy policy = new CacheItemPolicy () {
            AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration,
            SlidingExpiration = new TimeSpan ( 0, 15, 0 )
        };
        private ErzatsEnum ( string CacheKey )
            : base ( CacheKey, policy ) {
        }
        public ErzatsEnum Instance1 {
            get {
                ErzatsEnum result = ErzatsEnumBase.Cache.Get ( "Instance1" );
                if ( result == null )
                   result = new ErzatsEnum ( "Instance1" );
                return result;
            }
        }
        public ErzatsEnum Instance2 {
            get {
                ErzatsEnum result = ErzatsEnumBase.Cache.Get ( "Instance2" );
                if ( result == null )
                   result = new ErzatsEnum ( "Instance2" );
                return result;
            }
        }
    }
    
  5. 希望其中一些证明有用:)