强制C#编译器创建未使用的对象实例

时间:2010-06-02 13:23:12

标签: c# compiler-construction instance jit

确切地说我想做什么:)至少对于一个特定的课程。 问题是,我创建了一个对象的静态实例,但我不能直接使用它。由于我在构造函数中执行了一些操作,比如将对象添加到列表中,因此在获取列表之前必须至少调用一次构造函数。

我猜编译器只是优化了未使用的对象。

必须有一个简单的解决方案: - /

修改

好吧,我可能会错过一些东西。让我发布我的代码。我为自定义枚举目的写了一个类。

        public class TypeSafeEnum<TNameType, TValueType>
        {
        protected readonly TNameType name;
        protected readonly TValueType value;

        private static List<TypeSafeEnum<TNameType, TValueType>> listEnums = new List<TypeSafeEnum<TNameType, TValueType>>();

        protected TypeSafeEnum(TNameType name, TValueType value)
        {
          this.name = name;
          this.value = value;

          listEnums.Add(this);
        }

        public TNameType Name
        {
          get { return name; }
        }

        public TValueType Value
        {
          get { return value; }
        }

        public static TypeSafeEnum<TNameType, TValueType> GetName(TNameType name)
        {
          TypeSafeEnum<TNameType, TValueType> tse = null;
          for (int i = 0; i < listEnums.Count; i++)
          {
            TypeSafeEnum<TNameType, TValueType> typeSafeEnum = listEnums[i];
            if (EqualityComparer<TNameType>.Default.Equals(typeSafeEnum.name, name))
            {
              tse = typeSafeEnum;            
            }
          }
          return tse;
        }

        public static TypeSafeEnum<TNameType, TValueType> GetValue(TValueType value)
        {
          TypeSafeEnum<TNameType, TValueType> tse = null;
          for (int i = 0; i < listEnums.Count; i++)
          {
            TypeSafeEnum<TNameType, TValueType> typeSafeEnum = listEnums[i];
            if (EqualityComparer<TValueType>.Default.Equals(typeSafeEnum.value, value))
            {
              tse = typeSafeEnum;
            }
          }
          return tse;
        }

        public static TNameType[] GetNames()
        {
          TNameType[] names = new TNameType[listEnums.Count];
          for (int i = 0; i < listEnums.Count; i++)
          {
            TypeSafeEnum<TNameType, TValueType> typeSafeEnum = listEnums[i];
            names[i] = typeSafeEnum.name;
          }
          return names;
        }

        public static TValueType[] GetValues()
        {
          TValueType[] values = new TValueType[listEnums.Count];
          for (int i = 0; i < listEnums.Count; i++)
          {
            TypeSafeEnum<TNameType, TValueType> typeSafeEnum = listEnums[i];
            values[i] = typeSafeEnum.value;
          }
          return values;
        }
        }


        public abstract class StringEnum : TypeSafeEnum<string, int>
        {
            protected StringEnum(string name, int value) : base(name, value)
            {
            }
        }


        public sealed class FileOptionEnum : StringEnum
        {
            public static readonly FileOptionEnum Name = new FileOptionEnum("Name", 0);
            public static readonly FileOptionEnum Extension = new FileOptionEnum("Extension", 1);
            public static readonly FileOptionEnum Size = new FileOptionEnum("Size", 2);
            public static readonly FileOptionEnum LastModified = new FileOptionEnum("Last Modified", 3);
            public static readonly FileOptionEnum LastOpened = new FileOptionEnum("Last Opened", 4);
            public static readonly FileOptionEnum Created = new FileOptionEnum("Created", 5);

            public FileOptionEnum(string name, int value) : base(name, value)
            {
            }
        }

以下是我如何使用它:

        // if I omit this line it returns me empty array
        FileOptionEnum @enum = FileOptionEnum.Name;
        string[] names = FileOptionEnum.GetNames();
        cbFileOptions.Items.AddRange(names);

5 个答案:

答案 0 :(得分:2)

你可以简单地写

new YourObject();

这不会被优化掉 但是,除非类的构造函数在某处保存自己(例如,将对象添加到列表或静态字段,或将事件处理程序添加到其他位置),否则该对象可能会立即被垃圾收集。

答案 1 :(得分:2)

首先,请验证编译器是否确实优化了代码。机会是,它确实没有:如果您的构造函数调用有副作用,编译器实际上没有权利摆脱它。

如果它确实被优化掉了,你可以使用GC.KeepAlive方法来保证对象保持不变:

GC.KeepAlive( new MyObj() );

这种方法并没有真正做任何事情 - 它有空体。但它的特殊之处在于它无法优化。所以你用一些参数调用它,那么这个参数也不能被优化掉。

答案 2 :(得分:1)

你的想法不起作用。

静态List<TypeSafeEnum<TNameType, TValueType>> listEnums字段将由具有相同名称和值类型的所有TypeSafeEnum类共享。

要解决该问题,请为实际的枚举类添加一个参数,如下所示:

public class TypeSafeEnum<TEnum, TName, TValue> where TEnum : TypeSafeEnum<TEnum, TName, TValue>

(然后,您可以使用TypeSafeEnum<...>替换所有TEnum字段和参数

我很确定这也会解决你的实际问题 由于基类TypeSafeEnum类现在引用了继承的枚举类,因此继承的类'静态构造函数将运行,初始化值。

答案 3 :(得分:0)

如果您只是使用某些静态功能,为什么要使用实例呢?创建一个静态类,并使用静态“Initialize()”方法,您可以调用该方法来设置对象。

答案 4 :(得分:0)

在您尝试显式访问静态成员之前,不保证会初始化静态成员。您可以通过创建显式静态构造函数(以避免beforeFieldInit行为)并显式访问静态方法(如虚拟Init方法)来强制静态初始化来解决此问题。