1 //---------------------------------------------------------------------
2 // <copyright file="EnumType.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
8 //---------------------------------------------------------------------
10 namespace System.Data.Metadata.Edm
12 using System.Diagnostics;
13 using System.Globalization;
17 /// Represents an enumeration type.
19 public class EnumType : SimpleType
24 /// A collection of enumeration members for this enumeration type
26 private readonly ReadOnlyMetadataCollection<EnumMember> _members =
27 new ReadOnlyMetadataCollection<EnumMember>(new MetadataCollection<EnumMember>());
30 /// Indicates whether the enum type is defined as flags (i.e. can be treated as a bit field)
32 private readonly bool _isFlags;
35 /// Underlying type of this enumeration type.
37 private readonly PrimitiveType _underlyingType;
43 /// Initializes a new instance of the EnumType class. This default constructor is used for bootstraping
47 _underlyingType = PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32);
52 /// Initializes a new instance of the EnumType class by using the specified <paramref name="name"/>,
53 /// <paramref name="namespaceName"/> and <paramref name="isFlags"/>.
55 /// <param name="name">The name of this enum type.</param>
56 /// <param name="namespaceName">The namespace this enum type belongs to.</param>
57 /// <param name="isFlags">Indicates whether the enum type is defined as flags (i.e. can be treated as a bit field).</param>
58 /// <param name="underlyingType">Underlying type of this enumeration type.</param>
59 /// <param name="dataSpace">DataSpace this enum type lives in. Can be either CSpace or OSpace</param>
60 /// <exception cref="System.ArgumentNullException">Thrown if name or namespace arguments are null</exception>
61 /// <remarks>Note that enums live only in CSpace.</remarks>
62 internal EnumType(string name, string namespaceName, PrimitiveType underlyingType, bool isFlags, DataSpace dataSpace)
63 : base(name, namespaceName, dataSpace)
65 Debug.Assert(underlyingType != null, "underlyingType != null");
66 Debug.Assert(Helper.IsSupportedEnumUnderlyingType(underlyingType.PrimitiveTypeKind), "Unsupported underlying type for enum.");
67 Debug.Assert(dataSpace == DataSpace.CSpace || dataSpace == DataSpace.OSpace, "Enums can be only defined in CSpace or OSpace.");
70 _underlyingType = underlyingType;
74 /// Initializes a new instance of the EnumType class from CLR enumeration type.
76 /// <param name="clrType">
77 /// CLR enumeration type to create EnumType from.
80 /// Note that this method expects that the <paramref name="clrType"/> is a valid CLR enum type
81 /// whose underlying type is a valid EDM primitive type.
82 /// Ideally this constructor should be protected and internal (Family and Assembly modifier) but
83 /// C# does not support this. In order to not expose this constructor to everyone internal is the
86 internal EnumType(Type clrType) :
87 base(clrType.Name, clrType.Namespace ?? string.Empty, DataSpace.OSpace)
89 Debug.Assert(clrType != null, "clrType != null");
90 Debug.Assert(clrType.IsEnum, "enum type expected");
92 ClrProviderManifest.Instance.TryGetPrimitiveType(clrType.GetEnumUnderlyingType(), out _underlyingType);
94 Debug.Assert(_underlyingType != null, "only primitive types expected here.");
95 Debug.Assert(Helper.IsSupportedEnumUnderlyingType(_underlyingType.PrimitiveTypeKind),
96 "unsupported CLR types should have been filtered out by .TryGetPrimitiveType() method.");
98 _isFlags = clrType.GetCustomAttributes(typeof(FlagsAttribute), false).Any();
100 foreach (string name in Enum.GetNames(clrType))
105 Convert.ChangeType(Enum.Parse(clrType, name), clrType.GetEnumUnderlyingType(), CultureInfo.InvariantCulture)));
114 /// Returns the kind of the type
116 public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.EnumType; } }
119 /// Gets a collection of enumeration members for this enumeration type.
121 [MetadataProperty(BuiltInTypeKind.EnumMember, true)]
122 public ReadOnlyMetadataCollection<EnumMember> Members
124 get { return _members; }
128 /// Gets a value indicating whether the enum type is defined as flags (i.e. can be treated as a bit field)
130 [MetadataProperty(PrimitiveTypeKind.Boolean, false)]
133 get { return _isFlags; }
137 /// Gets the underlying type for this enumeration type.
139 [MetadataProperty(BuiltInTypeKind.PrimitiveType, false)]
140 public PrimitiveType UnderlyingType
142 get { return _underlyingType; }
150 /// Sets this item to be readonly, once this is set, the item will never be writable again.
152 internal override void SetReadOnly()
157 this.Members.Source.SetReadOnly();
162 /// Adds the specified member to the member collection
164 /// <param name="enumMember">Enumeration member to add to the member collection.</param>
165 internal void AddMember(EnumMember enumMember)
167 Debug.Assert(enumMember != null, "enumMember != null");
168 Debug.Assert(Helper.IsEnumMemberValueInRange(UnderlyingType.PrimitiveTypeKind, Convert.ToInt64(enumMember.Value, CultureInfo.InvariantCulture)));
169 Debug.Assert(enumMember.Value.GetType() == UnderlyingType.ClrEquivalentType);
171 this.Members.Source.Add(enumMember);
178 /// Represents an enumeration type that has a reference to the backing CLR type.
180 internal sealed class ClrEnumType : EnumType
182 /// <summary>cached CLR type handle, allowing the Type reference to be GC'd</summary>
183 private readonly System.RuntimeTypeHandle _type;
185 private readonly string _cspaceTypeName;
188 /// Initializes a new instance of ClrEnumType class with properties from the CLR type.
190 /// <param name="clrType">The CLR type to construct from.</param>
191 /// <param name="cspaceNamespaceName">CSpace namespace name.</param>
192 /// <param name="cspaceTypeName">CSpace type name.</param>
193 internal ClrEnumType(Type clrType, string cspaceNamespaceName, string cspaceTypeName)
196 Debug.Assert(clrType != null, "clrType != null");
197 Debug.Assert(clrType.IsEnum, "enum type expected");
198 Debug.Assert(!String.IsNullOrEmpty(cspaceNamespaceName) && !String.IsNullOrEmpty(cspaceTypeName), "Mapping information must never be null");
200 _type = clrType.TypeHandle;
201 _cspaceTypeName = cspaceNamespaceName + "." + cspaceTypeName;
205 /// Gets the clr type backing this enum type.
207 internal override System.Type ClrType
209 get { return Type.GetTypeFromHandle(_type); }
213 /// Get the full CSpaceTypeName for this enum type.
215 internal string CSpaceTypeName
219 return _cspaceTypeName;