diff Implab/Automaton/EnumAlphabet.cs @ 164:ec35731ae299 ref20160224

Almost complete DFA refactoring
author cin
date Thu, 25 Feb 2016 02:11:13 +0300
parents 0526412bbb26
children c32688129f14
line wrap: on
line diff
--- a/Implab/Automaton/EnumAlphabet.cs	Wed Feb 24 20:12:52 2016 +0300
+++ b/Implab/Automaton/EnumAlphabet.cs	Thu Feb 25 02:11:13 2016 +0300
@@ -12,46 +12,49 @@
     /// <typeparam name="T">Тип перечислений</typeparam>
     public class EnumAlphabet<T> : IndexedAlphabetBase<T> where T : struct, IConvertible {
         [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
-        static readonly T[] _symbols;
-        static readonly EnumAlphabet<T> _fullAlphabet;
+        static readonly Lazy<T[]> _symbols = new Lazy<T[]>(GetSymbols);
+
+        [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
+        static readonly Lazy<EnumAlphabet<T>> _fullAlphabet = new Lazy<EnumAlphabet<T>>(CreateEnumAlphabet);
+
+        static EnumAlphabet<T> CreateEnumAlphabet() {
+            var symbols = _symbols.Value;
 
-        [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
-        static EnumAlphabet() {
+            if (
+                symbols[symbols.Length - 1].ToInt32(CultureInfo.InvariantCulture) >= symbols.Length
+                || symbols[0].ToInt32(CultureInfo.InvariantCulture) != 0
+            )
+                throw new InvalidOperationException("The specified enumeration must be zero-based and continuously numbered");
+
+            return new EnumAlphabet<T>(symbols.Select(x => x.ToInt32(CultureInfo.InvariantCulture)).ToArray());
+        }
+
+        static T[] GetSymbols() {
             if (!typeof(T).IsEnum)
                 throw new InvalidOperationException("Invalid generic parameter, enumeration is required");
 
             if (Enum.GetUnderlyingType(typeof(T)) != typeof(Int32))
                 throw new InvalidOperationException("Only enums based on Int32 are supported");
-
-            _symbols = ((T[])Enum.GetValues(typeof(T)))
+            
+            return ((T[])Enum.GetValues(typeof(T)))
                 .OrderBy(x => x.ToInt32(CultureInfo.InvariantCulture))
                 .ToArray();
-
-            if (
-                _symbols[_symbols.Length - 1].ToInt32(CultureInfo.InvariantCulture) >= _symbols.Length
-                || _symbols[0].ToInt32(CultureInfo.InvariantCulture) != 0
-            )
-                throw new InvalidOperationException("The specified enumeration must be zero-based and continuously numbered");
-
-            _fullAlphabet = new EnumAlphabet<T>(_symbols.Select(x => x.ToInt32(CultureInfo.InvariantCulture)).ToArray());
         }
 
-        
-
         public static EnumAlphabet<T> FullAlphabet {
             get {
-                return _fullAlphabet;
+                return _fullAlphabet.Value;
             }
         }
 
 
         public EnumAlphabet()
-            : base(_symbols.Length) {
+            : base(_symbols.Value.Length) {
         }
 
         public EnumAlphabet(int[] map)
             : base(map) {
-            Debug.Assert(map.Length == _symbols.Length);
+            Debug.Assert(map.Length == _symbols.Value.Length);
         }
 
 
@@ -60,7 +63,7 @@
         }
 
         public override IEnumerable<T> InputSymbols {
-            get { return _symbols; }
+            get { return _symbols.Value; }
         }
 
     }