Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / clr / src / BCL / System / Collections / Generic / EqualityComparer.cs / 2 / EqualityComparer.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== using System; using System.Collections; using System.Collections.Generic; namespace System.Collections.Generic { using System.Globalization; using System.Runtime.CompilerServices; [Serializable()] [TypeDependencyAttribute("System.Collections.Generic.GenericEqualityComparer`1")] public abstract class EqualityComparer: IEqualityComparer, IEqualityComparer { static EqualityComparer defaultComparer; public static EqualityComparer Default { get { EqualityComparer comparer = defaultComparer; if (comparer == null) { comparer = CreateComparer(); defaultComparer = comparer; } return comparer; } } private static EqualityComparer CreateComparer() { Type t = typeof(T); // Specialize type byte for performance reasons if (t == typeof(byte)) { return (EqualityComparer )(object)(new ByteEqualityComparer()); } // If T implements IEquatable return a GenericEqualityComparer if (typeof(IEquatable ).IsAssignableFrom(t)) { //return (EqualityComparer )Activator.CreateInstance(typeof(GenericEqualityComparer<>).MakeGenericType(t)); return (EqualityComparer )(typeof(GenericEqualityComparer ).TypeHandle.CreateInstanceForAnotherGenericParameter(t)); } // If T is a Nullable where U implements IEquatable return a NullableEqualityComparer if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) { Type u = t.GetGenericArguments()[0]; if (typeof(IEquatable<>).MakeGenericType(u).IsAssignableFrom(u)) { //return (EqualityComparer )Activator.CreateInstance(typeof(NullableEqualityComparer<>).MakeGenericType(u)); return (EqualityComparer )(typeof(NullableEqualityComparer ).TypeHandle.CreateInstanceForAnotherGenericParameter(u)); } } // Otherwise return an ObjectEqualityComparer return new ObjectEqualityComparer (); } public abstract bool Equals(T x, T y); public abstract int GetHashCode(T obj); internal virtual int IndexOf(T[] array, T value, int startIndex, int count) { int endIndex = startIndex + count; for (int i = startIndex; i < endIndex; i++) { if (Equals(array[i], value)) return i; } return -1; } internal virtual int LastIndexOf(T[] array, T value, int startIndex, int count) { int endIndex = startIndex - count + 1; for (int i = startIndex; i >= endIndex; i--) { if (Equals(array[i], value)) return i; } return -1; } int IEqualityComparer.GetHashCode(object obj) { if (obj == null) return 0; if (obj is T) return GetHashCode((T)obj); ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison); return 0; } bool IEqualityComparer.Equals(object x, object y) { if (x == y) return true; if (x == null || y == null) return false; if ((x is T) && (y is T)) return Equals((T)x, (T)y); ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison); return false; } } // The methods in this class look identical to the inherited methods, but the calls // to Equal bind to IEquatable .Equals(T) instead of Object.Equals(Object) [Serializable()] internal class GenericEqualityComparer : EqualityComparer where T: IEquatable { public override bool Equals(T x, T y) { if (x != null) { if (y != null) return x.Equals(y); return false; } if (y != null) return false; return true; } public override int GetHashCode(T obj) { if (obj == null) return 0; return obj.GetHashCode(); } internal override int IndexOf(T[] array, T value, int startIndex, int count) { int endIndex = startIndex + count; if (value == null) { for (int i = startIndex; i < endIndex; i++) { if (array[i] == null) return i; } } else { for (int i = startIndex; i < endIndex; i++) { if (array[i] != null && array[i].Equals(value)) return i; } } return -1; } internal override int LastIndexOf(T[] array, T value, int startIndex, int count) { int endIndex = startIndex - count + 1; if (value == null) { for (int i = startIndex; i >= endIndex; i--) { if (array[i] == null) return i; } } else { for (int i = startIndex; i >= endIndex; i--) { if (array[i] != null && array[i].Equals(value)) return i; } } return -1; } // Equals method for the comparer itself. public override bool Equals(Object obj){ GenericEqualityComparer comparer = obj as GenericEqualityComparer ; return comparer != null; } public override int GetHashCode() { return this.GetType().Name.GetHashCode(); } } [Serializable()] internal class NullableEqualityComparer : EqualityComparer > where T : struct, IEquatable { public override bool Equals(Nullable x, Nullable y) { if (x.HasValue) { if (y.HasValue) return x.value.Equals(y.value); return false; } if (y.HasValue) return false; return true; } public override int GetHashCode(Nullable obj) { return obj.GetHashCode(); } internal override int IndexOf(Nullable [] array, Nullable value, int startIndex, int count) { int endIndex = startIndex + count; if (!value.HasValue) { for (int i = startIndex; i < endIndex; i++) { if (!array[i].HasValue) return i; } } else { for (int i = startIndex; i < endIndex; i++) { if (array[i].HasValue && array[i].value.Equals(value.value)) return i; } } return -1; } internal override int LastIndexOf(Nullable [] array, Nullable value, int startIndex, int count) { int endIndex = startIndex - count + 1; if (!value.HasValue) { for (int i = startIndex; i >= endIndex; i--) { if (!array[i].HasValue) return i; } } else { for (int i = startIndex; i >= endIndex; i--) { if (array[i].HasValue && array[i].value.Equals(value.value)) return i; } } return -1; } // Equals method for the comparer itself. public override bool Equals(Object obj){ NullableEqualityComparer comparer = obj as NullableEqualityComparer ; return comparer != null; } public override int GetHashCode() { return this.GetType().Name.GetHashCode(); } } [Serializable()] internal class ObjectEqualityComparer : EqualityComparer { public override bool Equals(T x, T y) { if (x != null) { if (y != null) return x.Equals(y); return false; } if (y != null) return false; return true; } public override int GetHashCode(T obj) { if (obj == null) return 0; return obj.GetHashCode(); } internal override int IndexOf(T[] array, T value, int startIndex, int count) { int endIndex = startIndex + count; if (value == null) { for (int i = startIndex; i < endIndex; i++) { if (array[i] == null) return i; } } else { for (int i = startIndex; i < endIndex; i++) { if (array[i] != null && array[i].Equals(value)) return i; } } return -1; } internal override int LastIndexOf(T[] array, T value, int startIndex, int count) { int endIndex = startIndex - count + 1; if (value == null) { for (int i = startIndex; i >= endIndex; i--) { if (array[i] == null) return i; } } else { for (int i = startIndex; i >= endIndex; i--) { if (array[i] != null && array[i].Equals(value)) return i; } } return -1; } // Equals method for the comparer itself. public override bool Equals(Object obj){ ObjectEqualityComparer comparer = obj as ObjectEqualityComparer ; return comparer != null; } public override int GetHashCode() { return this.GetType().Name.GetHashCode(); } } // Performance of IndexOf on byte array is very important for some scenarios. // We will call the C runtime function memchr, which is optimized. [Serializable()] internal class ByteEqualityComparer: EqualityComparer { public override bool Equals(byte x, byte y) { return x == y; } public override int GetHashCode(byte b) { return b.GetHashCode(); } internal unsafe override int IndexOf(byte[] array, byte value, int startIndex, int count) { if (array==null) throw new ArgumentNullException("array"); if (startIndex < 0) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); if (count > array.Length - startIndex) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); if (count == 0) return -1; fixed (byte* pbytes = array) { return Buffer.IndexOfByte(pbytes, value, startIndex, count); } } internal override int LastIndexOf(byte[] array, byte value, int startIndex, int count) { int endIndex = startIndex - count + 1; for (int i = startIndex; i >= endIndex; i--) { if (array[i] == value) return i; } return -1; } // Equals method for the comparer itself. public override bool Equals(Object obj){ ByteEqualityComparer comparer = obj as ByteEqualityComparer; return comparer != null; } public override int GetHashCode() { return this.GetType().Name.GetHashCode(); } } } // 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
- MethodExpr.cs
- DrawingContextWalker.cs
- CharKeyFrameCollection.cs
- ContainerParaClient.cs
- RenderDataDrawingContext.cs
- ExecutionEngineException.cs
- TraceProvider.cs
- AutomationEventArgs.cs
- StatusBarDrawItemEvent.cs
- DocumentManager.cs
- WebPartConnectVerb.cs
- FormsAuthenticationModule.cs
- NodeFunctions.cs
- DataBoundControlActionList.cs
- ExpressionBuilderCollection.cs
- XmlArrayItemAttributes.cs
- ElementFactory.cs
- ControlCollection.cs
- EditorPartChrome.cs
- DeriveBytes.cs
- Group.cs
- CriticalFinalizerObject.cs
- TimeSpanParse.cs
- WpfXamlLoader.cs
- RSAPKCS1SignatureFormatter.cs
- LineBreak.cs
- ImageCreator.cs
- EventProviderTraceListener.cs
- DataGridViewButtonColumn.cs
- Vector3dCollection.cs
- SqlPersonalizationProvider.cs
- DictionaryContent.cs
- InvokeSchedule.cs
- PropertyGroupDescription.cs
- QueryContinueDragEvent.cs
- ObjectDataSourceWizardForm.cs
- ImageAutomationPeer.cs
- XmlAggregates.cs
- RangeValuePatternIdentifiers.cs
- Pair.cs
- FlowDocumentPaginator.cs
- FamilyMap.cs
- DefaultAsyncDataDispatcher.cs
- MyContact.cs
- ConfigurationFileMap.cs
- BuildManager.cs
- AppSettingsExpressionBuilder.cs
- TextTreeRootTextBlock.cs
- ConnectionProviderAttribute.cs
- DbReferenceCollection.cs
- IsolatedStorageException.cs
- DropDownList.cs
- XmlBinaryReaderSession.cs
- DispatchChannelSink.cs
- KeyFrames.cs
- ExpressionBuilderCollection.cs
- ProxyElement.cs
- metadatamappinghashervisitor.hashsourcebuilder.cs
- VisualStyleInformation.cs
- UpDownBase.cs
- UserPreferenceChangedEventArgs.cs
- OutOfMemoryException.cs
- Ipv6Element.cs
- HMACSHA512.cs
- shaper.cs
- Attachment.cs
- FileDataSourceCache.cs
- BamlTreeNode.cs
- SymbolMethod.cs
- XmlDocumentFragment.cs
- ServicePointManager.cs
- PtsCache.cs
- RegisteredDisposeScript.cs
- RepeatInfo.cs
- ConfigurationElementCollection.cs
- ELinqQueryState.cs
- HandlerFactoryWrapper.cs
- ControlEvent.cs
- EnlistmentState.cs
- DataSet.cs
- NetworkInformationPermission.cs
- ViewManager.cs
- TextEncodedRawTextWriter.cs
- FixedSOMPage.cs
- ModifierKeysValueSerializer.cs
- SamlSecurityToken.cs
- ExpressionsCollectionEditor.cs
- Pair.cs
- OletxEnlistment.cs
- RootBrowserWindowProxy.cs
- DataList.cs
- SpotLight.cs
- SchemaConstraints.cs
- BindingSource.cs
- BaseCodeDomTreeGenerator.cs
- EvidenceTypeDescriptor.cs
- WindowsUpDown.cs
- OletxEnlistment.cs
- DoneReceivingAsyncResult.cs
- _DigestClient.cs