Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DLinq / Dlinq / SqlClient / Common / TypeSystem.cs / 1 / 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
- HandleRef.cs
- MouseActionValueSerializer.cs
- RuntimeHandles.cs
- EntityEntry.cs
- ValidationErrorEventArgs.cs
- DebugView.cs
- InputLanguageCollection.cs
- CodeTypeDelegate.cs
- ISAPIWorkerRequest.cs
- UserControlAutomationPeer.cs
- ScrollableControl.cs
- AccessibilityHelperForXpWin2k3.cs
- X509ChainPolicy.cs
- wgx_commands.cs
- ContainerParagraph.cs
- GridViewSortEventArgs.cs
- BooleanToVisibilityConverter.cs
- HttpListener.cs
- GestureRecognizer.cs
- BooleanKeyFrameCollection.cs
- Console.cs
- ReflectionTypeLoadException.cs
- ValueProviderWrapper.cs
- WrappedDispatcherException.cs
- ProcessHost.cs
- ControlCachePolicy.cs
- AjaxFrameworkAssemblyAttribute.cs
- CodeTypeReferenceCollection.cs
- Variable.cs
- FilterElement.cs
- BaseCAMarshaler.cs
- XPathNavigator.cs
- SchemaReference.cs
- GlyphCache.cs
- SafeProcessHandle.cs
- MailHeaderInfo.cs
- FormViewDesigner.cs
- GetPolicyDetailsRequest.cs
- AnimationClockResource.cs
- BrushConverter.cs
- WindowsRichEdit.cs
- EpmCustomContentSerializer.cs
- BitmapEffectInput.cs
- Stack.cs
- SoapIgnoreAttribute.cs
- PresentationSource.cs
- GroupBoxDesigner.cs
- LicenseContext.cs
- JpegBitmapDecoder.cs
- ConfigurationSectionGroupCollection.cs
- assertwrapper.cs
- ErrorInfoXmlDocument.cs
- ConfigPathUtility.cs
- QueryContinueDragEvent.cs
- XomlCompilerParameters.cs
- EdmMember.cs
- SamlAttributeStatement.cs
- ShellProvider.cs
- MobileResource.cs
- DefinitionBase.cs
- Parallel.cs
- TypeInitializationException.cs
- ButtonBase.cs
- TypeCollectionPropertyEditor.cs
- DeflateStream.cs
- BindingWorker.cs
- EntityDataSourceStatementEditor.cs
- Action.cs
- TreeNodeBindingCollection.cs
- EventTask.cs
- SystemIcmpV6Statistics.cs
- AnnotationObservableCollection.cs
- CodeAccessPermission.cs
- ArgIterator.cs
- DataGridViewCellFormattingEventArgs.cs
- RolePrincipal.cs
- OleDbMetaDataFactory.cs
- filewebresponse.cs
- WebCodeGenerator.cs
- SapiGrammar.cs
- Interlocked.cs
- ViewBox.cs
- EventTrigger.cs
- MouseBinding.cs
- Brush.cs
- SessionStateContainer.cs
- GeometryCollection.cs
- PageWrapper.cs
- Hex.cs
- DbDeleteCommandTree.cs
- TdsParserStateObject.cs
- TextBoxBaseDesigner.cs
- GuidTagList.cs
- SecurityCriticalDataForSet.cs
- WorkflowWebService.cs
- HandlerMappingMemo.cs
- XmlAnyElementAttributes.cs
- SubclassTypeValidator.cs
- XmlSchemaSet.cs
- Normalization.cs