Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Collections / Generic / EqualityComparer.cs / 1305376 / 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; using System.Runtime.CompilerServices; using System.Diagnostics.Contracts; [Serializable] [TypeDependencyAttribute("System.Collections.Generic.GenericEqualityComparer`1")] [TypeDependencyAttribute("System.Collections.Generic.EnumEqualityComparer`1")] public abstract class EqualityComparer: IEqualityComparer, IEqualityComparer { static EqualityComparer defaultComparer; public static EqualityComparer Default { [System.Security.SecuritySafeCritical] // auto-generated #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { Contract.Ensures(Contract.Result >() != null); EqualityComparer comparer = defaultComparer; if (comparer == null) { comparer = CreateComparer(); defaultComparer = comparer; } return comparer; } } [System.Security.SecuritySafeCritical] // auto-generated private static EqualityComparer CreateComparer() { Contract.Ensures(Contract.Result >() != null); RuntimeType t = (RuntimeType)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 )RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer ), t); } // If T is a Nullable where U implements IEquatable return a NullableEqualityComparer if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IEquatable<>).MakeGenericType(u).IsAssignableFrom(u)) { //return (EqualityComparer )Activator.CreateInstance(typeof(NullableEqualityComparer<>).MakeGenericType(u)); return (EqualityComparer )RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer ), u); } } // If T is an int-based Enum, return an EnumEqualityComparer // If you update this check, you need to update the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST case in getILIntrinsicImplementation if (t.IsEnum && Enum.GetUnderlyingType(t) == typeof(int)) { return (EqualityComparer )RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer ), t); } // Otherwise return an ObjectEqualityComparer return new ObjectEqualityComparer (); } [Pure] public abstract bool Equals(T x, T y); [Pure] 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 { [Pure] 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; } [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif 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 { [Pure] 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; } [Pure] 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 { [Pure] 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; } [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif 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 { [Pure] public override bool Equals(byte x, byte y) { return x == y; } [Pure] public override int GetHashCode(byte b) { return b.GetHashCode(); } [System.Security.SecuritySafeCritical] // auto-generated 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")); Contract.EndContractBlock(); 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(); } } [Serializable] internal sealed class EnumEqualityComparer : EqualityComparer where T: struct { [Pure] [System.Security.SecuritySafeCritical] public override bool Equals(T x, T y) { int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(x); int y_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(y); return x_final == y_final; } [Pure] [System.Security.SecuritySafeCritical] public override int GetHashCode(T obj) { int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(obj); return x_final.GetHashCode(); } // Equals method for the comparer itself. public override bool Equals(Object obj){ EnumEqualityComparer comparer = obj as EnumEqualityComparer ; 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. // // ==--== // [....] // using System; using System.Collections; using System.Collections.Generic; namespace System.Collections.Generic { using System.Globalization; using System.Runtime; using System.Runtime.CompilerServices; using System.Diagnostics.Contracts; [Serializable] [TypeDependencyAttribute("System.Collections.Generic.GenericEqualityComparer`1")] [TypeDependencyAttribute("System.Collections.Generic.EnumEqualityComparer`1")] public abstract class EqualityComparer: IEqualityComparer, IEqualityComparer { static EqualityComparer defaultComparer; public static EqualityComparer Default { [System.Security.SecuritySafeCritical] // auto-generated #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif get { Contract.Ensures(Contract.Result >() != null); EqualityComparer comparer = defaultComparer; if (comparer == null) { comparer = CreateComparer(); defaultComparer = comparer; } return comparer; } } [System.Security.SecuritySafeCritical] // auto-generated private static EqualityComparer CreateComparer() { Contract.Ensures(Contract.Result >() != null); RuntimeType t = (RuntimeType)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 )RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer ), t); } // If T is a Nullable where U implements IEquatable return a NullableEqualityComparer if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IEquatable<>).MakeGenericType(u).IsAssignableFrom(u)) { //return (EqualityComparer )Activator.CreateInstance(typeof(NullableEqualityComparer<>).MakeGenericType(u)); return (EqualityComparer )RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer ), u); } } // If T is an int-based Enum, return an EnumEqualityComparer // If you update this check, you need to update the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST case in getILIntrinsicImplementation if (t.IsEnum && Enum.GetUnderlyingType(t) == typeof(int)) { return (EqualityComparer )RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer ), t); } // Otherwise return an ObjectEqualityComparer return new ObjectEqualityComparer (); } [Pure] public abstract bool Equals(T x, T y); [Pure] 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 { [Pure] 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; } [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif 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 { [Pure] 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; } [Pure] 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 { [Pure] 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; } [Pure] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif 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 { [Pure] public override bool Equals(byte x, byte y) { return x == y; } [Pure] public override int GetHashCode(byte b) { return b.GetHashCode(); } [System.Security.SecuritySafeCritical] // auto-generated 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")); Contract.EndContractBlock(); 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(); } } [Serializable] internal sealed class EnumEqualityComparer : EqualityComparer where T: struct { [Pure] [System.Security.SecuritySafeCritical] public override bool Equals(T x, T y) { int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(x); int y_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(y); return x_final == y_final; } [Pure] [System.Security.SecuritySafeCritical] public override int GetHashCode(T obj) { int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(obj); return x_final.GetHashCode(); } // Equals method for the comparer itself. public override bool Equals(Object obj){ EnumEqualityComparer comparer = obj as EnumEqualityComparer ; return comparer != null; } public override int GetHashCode() { return this.GetType().Name.GetHashCode(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SequenceNumber.cs
- KeyTime.cs
- DefaultValueTypeConverter.cs
- Currency.cs
- XmlILModule.cs
- DBSqlParser.cs
- DoubleAnimationBase.cs
- TextContainerChangeEventArgs.cs
- RestHandlerFactory.cs
- ConfigurationConverterBase.cs
- assemblycache.cs
- LocalValueEnumerator.cs
- PageVisual.cs
- LeafCellTreeNode.cs
- OutputCacheProfileCollection.cs
- EmptyReadOnlyDictionaryInternal.cs
- GridViewRowCollection.cs
- ResourcePermissionBase.cs
- Send.cs
- InstallerTypeAttribute.cs
- DataDocumentXPathNavigator.cs
- ComboBox.cs
- Attributes.cs
- KeyNotFoundException.cs
- WindowsTreeView.cs
- ServicePointManagerElement.cs
- TextRange.cs
- ColumnMap.cs
- _StreamFramer.cs
- CmsInterop.cs
- NavigateUrlConverter.cs
- DataServiceContext.cs
- DataControlField.cs
- OperandQuery.cs
- DragDropManager.cs
- ServiceSecurityAuditElement.cs
- MetadataArtifactLoaderResource.cs
- DocumentApplicationJournalEntry.cs
- FontUnit.cs
- Formatter.cs
- Enlistment.cs
- InfoCardSymmetricCrypto.cs
- RegexCaptureCollection.cs
- PerformanceCounter.cs
- SendKeys.cs
- MediaTimeline.cs
- And.cs
- BitmapSizeOptions.cs
- InputMethodStateChangeEventArgs.cs
- GrammarBuilderBase.cs
- ApplyImportsAction.cs
- WebPartDeleteVerb.cs
- SqlMetaData.cs
- ResolvedKeyFrameEntry.cs
- WhitespaceRuleReader.cs
- Regex.cs
- ZipIOLocalFileDataDescriptor.cs
- Connector.xaml.cs
- MetabaseSettings.cs
- OperationContextScope.cs
- UpdatePanelTrigger.cs
- WindowsTreeView.cs
- SqlUtil.cs
- GraphicsState.cs
- AnimationLayer.cs
- XmlTextReaderImplHelpers.cs
- ProcessHostServerConfig.cs
- PropertyInfoSet.cs
- CodeTryCatchFinallyStatement.cs
- VirtualPath.cs
- ParseChildrenAsPropertiesAttribute.cs
- Vector3DKeyFrameCollection.cs
- RequestQueue.cs
- NavigationHelper.cs
- TypographyProperties.cs
- SafeNativeMethodsCLR.cs
- SchemaImporter.cs
- FrameworkContentElement.cs
- XPathNodePointer.cs
- SimpleHandlerBuildProvider.cs
- SingleAnimationBase.cs
- CurrentTimeZone.cs
- RecognitionEventArgs.cs
- TypeKeyValue.cs
- GridSplitterAutomationPeer.cs
- EpmSourcePathSegment.cs
- ToolZone.cs
- ObservableDictionary.cs
- DataBoundLiteralControl.cs
- ReadContentAsBinaryHelper.cs
- Group.cs
- UnicastIPAddressInformationCollection.cs
- Compiler.cs
- COM2IDispatchConverter.cs
- mediapermission.cs
- DrawingServices.cs
- CngKey.cs
- KeyEvent.cs
- PagePropertiesChangingEventArgs.cs
- GestureRecognizer.cs