Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Common / TypeSystem.cs / 1305376 / TypeSystem.cs
using System; using System.Collections.Generic; using System.Text; using System.Reflection; using System.Collections; using System.Security; using System.Security.Permissions; using System.Linq; namespace System.Data.Linq.SqlClient { internal static class TypeSystem { internal static bool IsSequenceType(Type seqType) { return seqType != typeof(string) && seqType != typeof(byte[]) && seqType != typeof(char[]) && FindIEnumerable(seqType) != null; } internal static bool HasIEnumerable(Type seqType) { return FindIEnumerable(seqType) != null; } private static Type FindIEnumerable(Type seqType) { if (seqType == null || seqType == typeof(string)) return null; if (seqType.IsArray) return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType()); if (seqType.IsGenericType) { foreach (Type arg in seqType.GetGenericArguments()) { Type ienum = typeof(IEnumerable<>).MakeGenericType(arg); if (ienum.IsAssignableFrom(seqType)) { return ienum; } } } Type[] ifaces = seqType.GetInterfaces(); if (ifaces != null && ifaces.Length > 0) { foreach (Type iface in ifaces) { Type ienum = FindIEnumerable(iface); if (ienum != null) return ienum; } } if (seqType.BaseType != null && seqType.BaseType != typeof(object)) { return FindIEnumerable(seqType.BaseType); } return null; } internal static Type GetFlatSequenceType(Type elementType) { Type ienum = FindIEnumerable(elementType); if (ienum != null) return ienum; return typeof(IEnumerable<>).MakeGenericType(elementType); } internal static Type GetSequenceType(Type elementType) { return typeof(IEnumerable<>).MakeGenericType(elementType); } internal static Type GetElementType(Type seqType) { Type ienum = FindIEnumerable(seqType); if (ienum == null) return seqType; return ienum.GetGenericArguments()[0]; } internal static bool IsNullableType(Type type) { return type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); } internal static bool IsNullAssignable(Type type) { return !type.IsValueType || IsNullableType(type); } internal static Type GetNonNullableType(Type type) { if (IsNullableType(type)) { return type.GetGenericArguments()[0]; } return type; } internal static Type GetMemberType(MemberInfo mi) { FieldInfo fi = mi as FieldInfo; if (fi != null) return fi.FieldType; PropertyInfo pi = mi as PropertyInfo; if (pi != null) return pi.PropertyType; EventInfo ei = mi as EventInfo; if (ei != null) return ei.EventHandlerType; return null; } internal static IEnumerableGetAllFields(Type type, BindingFlags flags) { Dictionary seen = new Dictionary (); Type currentType = type; do { foreach (FieldInfo fi in currentType.GetFields(flags)) { if (fi.IsPrivate || type == currentType) { MetaPosition mp = new MetaPosition(fi); seen[mp] = fi; } } currentType = currentType.BaseType; } while (currentType != null); return seen.Values; } internal static IEnumerable GetAllProperties(Type type, BindingFlags flags) { Dictionary seen = new Dictionary (); Type currentType = type; do { foreach (PropertyInfo pi in currentType.GetProperties(flags)) { if (type == currentType || IsPrivate(pi)) { MetaPosition mp = new MetaPosition(pi); seen[mp] = pi; } } currentType = currentType.BaseType; } while (currentType != null); return seen.Values; } private static bool IsPrivate(PropertyInfo pi) { MethodInfo mi = pi.GetGetMethod() ?? pi.GetSetMethod(); if (mi != null) { return mi.IsPrivate; } return true; } private static ILookup _sequenceMethods; internal static MethodInfo FindSequenceMethod(string name, Type[] args, params Type[] typeArgs) { if (_sequenceMethods == null) { _sequenceMethods = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).ToLookup(m => m.Name); } MethodInfo mi = _sequenceMethods[name].FirstOrDefault(m => ArgsMatchExact(m, args, typeArgs)); if (mi == null) return null; if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } internal static MethodInfo FindSequenceMethod(string name, IEnumerable sequence) { return FindSequenceMethod(name, new Type[] {sequence.GetType()}, new Type[] {GetElementType(sequence.GetType())}); } private static ILookup _queryMethods; internal static MethodInfo FindQueryableMethod(string name, Type[] args, params Type[] typeArgs) { if (_queryMethods == null) { _queryMethods = typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public).ToLookup(m => m.Name); } MethodInfo mi = _queryMethods[name].FirstOrDefault(m => ArgsMatchExact(m, args, typeArgs)); if (mi == null) throw Error.NoMethodInTypeMatchingArguments(typeof(Queryable)); if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } internal static MethodInfo FindStaticMethod(Type type, string name, Type[] args, params Type[] typeArgs) { MethodInfo mi = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .FirstOrDefault(m => m.Name == name && ArgsMatchExact(m, args, typeArgs)); if (mi == null) throw Error.NoMethodInTypeMatchingArguments(type); if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } private static bool ArgsMatchExact(MethodInfo m, Type[] argTypes, Type[] typeArgs) { ParameterInfo[] mParams = m.GetParameters(); if (mParams.Length != argTypes.Length) return false; if (!m.IsGenericMethodDefinition && m.IsGenericMethod && m.ContainsGenericParameters) { m = m.GetGenericMethodDefinition(); } if (m.IsGenericMethodDefinition) { if (typeArgs == null || typeArgs.Length == 0) return false; if (m.GetGenericArguments().Length != typeArgs.Length) return false; m = m.MakeGenericMethod(typeArgs); mParams = m.GetParameters(); } else if (typeArgs != null && typeArgs.Length > 0) { return false; } for (int i = 0, n = argTypes.Length; i < n; i++) { Type parameterType = mParams[i].ParameterType; if (parameterType == null) return false; Type argType = argTypes[i]; if (!parameterType.IsAssignableFrom(argType)) return false; } return true; } /// /// Returns true if the type is one of the built in simple types. /// internal static bool IsSimpleType(Type type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) type = type.GetGenericArguments()[0]; if (type.IsEnum) return true; if (type == typeof(Guid)) return true; TypeCode tc = Type.GetTypeCode(type); switch (tc) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: case TypeCode.Char: case TypeCode.String: case TypeCode.Boolean: case TypeCode.DateTime: return true; case TypeCode.Object: return (typeof(TimeSpan) == type) || (typeof(DateTimeOffset) == type); default: return false; } } } ////// Hashable MetaDataToken+Assembly. This type uniquely describes a metadata element /// like a MemberInfo. MetaDataToken by itself is not sufficient because its only /// unique within a single assembly. /// internal struct MetaPosition : IEqualityComparer, IEqualityComparer { private int metadataToken; private Assembly assembly; internal MetaPosition(MemberInfo mi) : this(mi.DeclaringType.Assembly, mi.MetadataToken) { } private MetaPosition(Assembly assembly, int metadataToken) { this.assembly = assembly; this.metadataToken = metadataToken; } // Equality is implemented here according to the advice in // CLR via C# 2ed, J. Richter, p 146. In particular, ValueType.Equals // should not be called for perf reasons. #region Object Members public override bool Equals(object obj) { if (obj == null) return false; if (obj.GetType() != this.GetType()) return false; return AreEqual(this, (MetaPosition)obj); } public override int GetHashCode() { return metadataToken; } #endregion #region IEqualityComparer Members public bool Equals(MetaPosition x, MetaPosition y) { return AreEqual(x, y); } public int GetHashCode(MetaPosition obj) { return obj.metadataToken; } #endregion #region IEqualityComparer Members bool IEqualityComparer.Equals(object x, object y) { return this.Equals((MetaPosition)x, (MetaPosition)y); } int IEqualityComparer.GetHashCode(object obj) { return this.GetHashCode((MetaPosition) obj); } #endregion private static bool AreEqual(MetaPosition x, MetaPosition y) { return (x.metadataToken == y.metadataToken) && (x.assembly == y.assembly); } // Since MetaPositions are immutable, we overload the equality operator // to test for value equality, rather than reference equality public static bool operator==(MetaPosition x, MetaPosition y) { return AreEqual(x, y); } public static bool operator !=(MetaPosition x, MetaPosition y) { return !AreEqual(x, y); } internal static bool AreSameMember(MemberInfo x, MemberInfo y) { if (x.MetadataToken != y.MetadataToken || x.DeclaringType.Assembly != y.DeclaringType.Assembly) { return false; } return true; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections.Generic; using System.Text; using System.Reflection; using System.Collections; using System.Security; using System.Security.Permissions; using System.Linq; namespace System.Data.Linq.SqlClient { internal static class TypeSystem { internal static bool IsSequenceType(Type seqType) { return seqType != typeof(string) && seqType != typeof(byte[]) && seqType != typeof(char[]) && FindIEnumerable(seqType) != null; } internal static bool HasIEnumerable(Type seqType) { return FindIEnumerable(seqType) != null; } private static Type FindIEnumerable(Type seqType) { if (seqType == null || seqType == typeof(string)) return null; if (seqType.IsArray) return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType()); if (seqType.IsGenericType) { foreach (Type arg in seqType.GetGenericArguments()) { Type ienum = typeof(IEnumerable<>).MakeGenericType(arg); if (ienum.IsAssignableFrom(seqType)) { return ienum; } } } Type[] ifaces = seqType.GetInterfaces(); if (ifaces != null && ifaces.Length > 0) { foreach (Type iface in ifaces) { Type ienum = FindIEnumerable(iface); if (ienum != null) return ienum; } } if (seqType.BaseType != null && seqType.BaseType != typeof(object)) { return FindIEnumerable(seqType.BaseType); } return null; } internal static Type GetFlatSequenceType(Type elementType) { Type ienum = FindIEnumerable(elementType); if (ienum != null) return ienum; return typeof(IEnumerable<>).MakeGenericType(elementType); } internal static Type GetSequenceType(Type elementType) { return typeof(IEnumerable<>).MakeGenericType(elementType); } internal static Type GetElementType(Type seqType) { Type ienum = FindIEnumerable(seqType); if (ienum == null) return seqType; return ienum.GetGenericArguments()[0]; } internal static bool IsNullableType(Type type) { return type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); } internal static bool IsNullAssignable(Type type) { return !type.IsValueType || IsNullableType(type); } internal static Type GetNonNullableType(Type type) { if (IsNullableType(type)) { return type.GetGenericArguments()[0]; } return type; } internal static Type GetMemberType(MemberInfo mi) { FieldInfo fi = mi as FieldInfo; if (fi != null) return fi.FieldType; PropertyInfo pi = mi as PropertyInfo; if (pi != null) return pi.PropertyType; EventInfo ei = mi as EventInfo; if (ei != null) return ei.EventHandlerType; return null; } internal static IEnumerable GetAllFields(Type type, BindingFlags flags) { Dictionary seen = new Dictionary (); Type currentType = type; do { foreach (FieldInfo fi in currentType.GetFields(flags)) { if (fi.IsPrivate || type == currentType) { MetaPosition mp = new MetaPosition(fi); seen[mp] = fi; } } currentType = currentType.BaseType; } while (currentType != null); return seen.Values; } internal static IEnumerable GetAllProperties(Type type, BindingFlags flags) { Dictionary seen = new Dictionary (); Type currentType = type; do { foreach (PropertyInfo pi in currentType.GetProperties(flags)) { if (type == currentType || IsPrivate(pi)) { MetaPosition mp = new MetaPosition(pi); seen[mp] = pi; } } currentType = currentType.BaseType; } while (currentType != null); return seen.Values; } private static bool IsPrivate(PropertyInfo pi) { MethodInfo mi = pi.GetGetMethod() ?? pi.GetSetMethod(); if (mi != null) { return mi.IsPrivate; } return true; } private static ILookup _sequenceMethods; internal static MethodInfo FindSequenceMethod(string name, Type[] args, params Type[] typeArgs) { if (_sequenceMethods == null) { _sequenceMethods = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).ToLookup(m => m.Name); } MethodInfo mi = _sequenceMethods[name].FirstOrDefault(m => ArgsMatchExact(m, args, typeArgs)); if (mi == null) return null; if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } internal static MethodInfo FindSequenceMethod(string name, IEnumerable sequence) { return FindSequenceMethod(name, new Type[] {sequence.GetType()}, new Type[] {GetElementType(sequence.GetType())}); } private static ILookup _queryMethods; internal static MethodInfo FindQueryableMethod(string name, Type[] args, params Type[] typeArgs) { if (_queryMethods == null) { _queryMethods = typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public).ToLookup(m => m.Name); } MethodInfo mi = _queryMethods[name].FirstOrDefault(m => ArgsMatchExact(m, args, typeArgs)); if (mi == null) throw Error.NoMethodInTypeMatchingArguments(typeof(Queryable)); if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } internal static MethodInfo FindStaticMethod(Type type, string name, Type[] args, params Type[] typeArgs) { MethodInfo mi = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .FirstOrDefault(m => m.Name == name && ArgsMatchExact(m, args, typeArgs)); if (mi == null) throw Error.NoMethodInTypeMatchingArguments(type); if (typeArgs != null) return mi.MakeGenericMethod(typeArgs); return mi; } private static bool ArgsMatchExact(MethodInfo m, Type[] argTypes, Type[] typeArgs) { ParameterInfo[] mParams = m.GetParameters(); if (mParams.Length != argTypes.Length) return false; if (!m.IsGenericMethodDefinition && m.IsGenericMethod && m.ContainsGenericParameters) { m = m.GetGenericMethodDefinition(); } if (m.IsGenericMethodDefinition) { if (typeArgs == null || typeArgs.Length == 0) return false; if (m.GetGenericArguments().Length != typeArgs.Length) return false; m = m.MakeGenericMethod(typeArgs); mParams = m.GetParameters(); } else if (typeArgs != null && typeArgs.Length > 0) { return false; } for (int i = 0, n = argTypes.Length; i < n; i++) { Type parameterType = mParams[i].ParameterType; if (parameterType == null) return false; Type argType = argTypes[i]; if (!parameterType.IsAssignableFrom(argType)) return false; } return true; } /// /// Returns true if the type is one of the built in simple types. /// internal static bool IsSimpleType(Type type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) type = type.GetGenericArguments()[0]; if (type.IsEnum) return true; if (type == typeof(Guid)) return true; TypeCode tc = Type.GetTypeCode(type); switch (tc) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: case TypeCode.Char: case TypeCode.String: case TypeCode.Boolean: case TypeCode.DateTime: return true; case TypeCode.Object: return (typeof(TimeSpan) == type) || (typeof(DateTimeOffset) == type); default: return false; } } } ////// Hashable MetaDataToken+Assembly. This type uniquely describes a metadata element /// like a MemberInfo. MetaDataToken by itself is not sufficient because its only /// unique within a single assembly. /// internal struct MetaPosition : IEqualityComparer, IEqualityComparer { private int metadataToken; private Assembly assembly; internal MetaPosition(MemberInfo mi) : this(mi.DeclaringType.Assembly, mi.MetadataToken) { } private MetaPosition(Assembly assembly, int metadataToken) { this.assembly = assembly; this.metadataToken = metadataToken; } // Equality is implemented here according to the advice in // CLR via C# 2ed, J. Richter, p 146. In particular, ValueType.Equals // should not be called for perf reasons. #region Object Members public override bool Equals(object obj) { if (obj == null) return false; if (obj.GetType() != this.GetType()) return false; return AreEqual(this, (MetaPosition)obj); } public override int GetHashCode() { return metadataToken; } #endregion #region IEqualityComparer Members public bool Equals(MetaPosition x, MetaPosition y) { return AreEqual(x, y); } public int GetHashCode(MetaPosition obj) { return obj.metadataToken; } #endregion #region IEqualityComparer Members bool IEqualityComparer.Equals(object x, object y) { return this.Equals((MetaPosition)x, (MetaPosition)y); } int IEqualityComparer.GetHashCode(object obj) { return this.GetHashCode((MetaPosition) obj); } #endregion private static bool AreEqual(MetaPosition x, MetaPosition y) { return (x.metadataToken == y.metadataToken) && (x.assembly == y.assembly); } // Since MetaPositions are immutable, we overload the equality operator // to test for value equality, rather than reference equality public static bool operator==(MetaPosition x, MetaPosition y) { return AreEqual(x, y); } public static bool operator !=(MetaPosition x, MetaPosition y) { return !AreEqual(x, y); } internal static bool AreSameMember(MemberInfo x, MemberInfo y) { if (x.MetadataToken != y.MetadataToken || x.DeclaringType.Assembly != y.DeclaringType.Assembly) { return false; } return true; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ContentDefinition.cs
- BindingValueChangedEventArgs.cs
- DoubleAnimationBase.cs
- FileDataSource.cs
- WebPartUserCapability.cs
- Utils.cs
- WebScriptEndpoint.cs
- TemplatePropertyEntry.cs
- QilTargetType.cs
- FormsIdentity.cs
- XmlMtomReader.cs
- UnsafeNativeMethods.cs
- COM2ComponentEditor.cs
- SafeLibraryHandle.cs
- CompiledIdentityConstraint.cs
- precedingsibling.cs
- BinaryFormatterWriter.cs
- FontCacheUtil.cs
- BaseParagraph.cs
- DecryptedHeader.cs
- DataGridViewMethods.cs
- AutomationElementIdentifiers.cs
- StorageModelBuildProvider.cs
- _AutoWebProxyScriptEngine.cs
- CryptoHandle.cs
- FolderBrowserDialog.cs
- HyperLinkField.cs
- SecurityDescriptor.cs
- DataGridViewComboBoxColumn.cs
- ItemMap.cs
- InstanceCreationEditor.cs
- ValueUnavailableException.cs
- StrongNameIdentityPermission.cs
- DelimitedListTraceListener.cs
- StandardCommands.cs
- Function.cs
- CounterCreationData.cs
- CallbackValidatorAttribute.cs
- NavigationPropertyEmitter.cs
- QueryConverter.cs
- DefaultSection.cs
- IdentityHolder.cs
- InternalCache.cs
- FormViewInsertEventArgs.cs
- CredentialCache.cs
- TableCell.cs
- RoleService.cs
- DiscoveryInnerClientAdhoc11.cs
- HttpListenerContext.cs
- XmlConverter.cs
- FileVersionInfo.cs
- DataKey.cs
- SecurityRuntime.cs
- HttpConfigurationContext.cs
- _ShellExpression.cs
- BamlTreeMap.cs
- NotSupportedException.cs
- PageThemeCodeDomTreeGenerator.cs
- ExtensibleSyndicationObject.cs
- InstanceDescriptor.cs
- CustomTypeDescriptor.cs
- OracleEncoding.cs
- CodeGenerator.cs
- TreeNodeMouseHoverEvent.cs
- RealProxy.cs
- DataGridAddNewRow.cs
- XmlFormatExtensionPrefixAttribute.cs
- CompressEmulationStream.cs
- ContentPlaceHolder.cs
- CacheHelper.cs
- PipeConnection.cs
- ProtocolsSection.cs
- ControlBuilderAttribute.cs
- BasicCellRelation.cs
- PropertyDescriptorCollection.cs
- HttpFileCollection.cs
- AttachedAnnotationChangedEventArgs.cs
- NativeMethods.cs
- ProfileModule.cs
- ArrayWithOffset.cs
- Repeater.cs
- InternalException.cs
- XmlUnspecifiedAttribute.cs
- PrtCap_Public.cs
- PngBitmapEncoder.cs
- DoubleAnimationClockResource.cs
- SpellerInterop.cs
- DataGridViewHitTestInfo.cs
- XmlnsDefinitionAttribute.cs
- XhtmlBasicListAdapter.cs
- Soap.cs
- XPathNavigator.cs
- MergablePropertyAttribute.cs
- HybridCollection.cs
- DictionaryEntry.cs
- ReceiveCompletedEventArgs.cs
- Grid.cs
- StandardCommandToolStripMenuItem.cs
- ClientSponsor.cs
- Subtree.cs