| File: System\Reflection\Metadata\MetadataStringComparer.cs | Web Access |
| Project: src\runtime\src\libraries\System.Reflection.Metadata\src\System.Reflection.Metadata.csproj (System.Reflection.Metadata) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Runtime.CompilerServices; namespace System.Reflection.Metadata { /// <summary> /// Provides string comparison helpers to query strings in metadata while /// avoiding allocation where possible. /// </summary> /// /// <remarks> /// No allocation is performed unless both the handle argument and the /// value argument contain non-ascii text. /// /// Obtain instances using <see cref="MetadataReader.StringComparer"/>. /// /// A default-initialized instance is useless and behaves as a null reference. /// /// The code is optimized such that there is no additional overhead in /// re-obtaining a comparer over hoisting it in to a local. /// /// That is to say that a construct like: /// /// <code> /// if (reader.StringComparer.Equals(typeDef.Namespace, "System") && /// reader.StringComparer.Equals(typeDef.Name, "Object") /// { /// // found System.Object /// } /// </code> /// /// is no less efficient than: /// /// <code> /// var comparer = reader.StringComparer; /// if (comparer.Equals(typeDef.Namespace, "System") && /// comparer.Equals(typeDef.Name, "Object") /// { /// // found System.Object /// } /// </code> /// /// The choice between them is therefore one of style and not performance. /// </remarks> public readonly struct MetadataStringComparer { private readonly MetadataReader _reader; internal MetadataStringComparer(MetadataReader reader) { Debug.Assert(reader != null); _reader = reader; } public bool Equals(StringHandle handle, string value) { return Equals(handle, value, ignoreCase: false); } public bool Equals(StringHandle handle, string value, bool ignoreCase) { ArgumentNullException.ThrowIfNull(value); return _reader.StringHeap.Equals(handle, value, _reader.UTF8Decoder, ignoreCase); } public bool Equals(NamespaceDefinitionHandle handle, string value) { return Equals(handle, value, ignoreCase: false); } public bool Equals(NamespaceDefinitionHandle handle, string value, bool ignoreCase) { ArgumentNullException.ThrowIfNull(value); if (handle.HasFullName) { return _reader.StringHeap.Equals(handle.GetFullName(), value, _reader.UTF8Decoder, ignoreCase); } return value == _reader.NamespaceCache.GetFullName(handle); } public bool Equals(DocumentNameBlobHandle handle, string value) { return Equals(handle, value, ignoreCase: false); } public bool Equals(DocumentNameBlobHandle handle, string value, bool ignoreCase) { ArgumentNullException.ThrowIfNull(value); return _reader.BlobHeap.DocumentNameEquals(handle, value, ignoreCase); } public bool StartsWith(StringHandle handle, string value) { return StartsWith(handle, value, ignoreCase: false); } public bool StartsWith(StringHandle handle, string value, bool ignoreCase) { ArgumentNullException.ThrowIfNull(value); return _reader.StringHeap.StartsWith(handle, value, _reader.UTF8Decoder, ignoreCase); } } }