1413 lines · 72.9 KB · C#
RawDownload
#if MONO
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Threading;
namespace System.Collections.Concurrent
{
    /// <summary>Represents a thread-safe collection of key-value pairs that can be accessed by multiple threads concurrently. </summary>
    /// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
    /// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
    [__DynamicallyInvokable, DebuggerDisplay("Count = {Count}"), ComVisible(false)]
    [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
    [Serializable]
    public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable
    {
        private class Tables
        {
            internal readonly ConcurrentDictionary<TKey, TValue>.Node[] m_buckets;
            internal readonly object[] m_locks;
            internal volatile int[] m_countPerLock;
            internal Tables(ConcurrentDictionary<TKey, TValue>.Node[] buckets, object[] locks, int[] countPerLock)
            {
                this.m_buckets = buckets;
                this.m_locks = locks;
                this.m_countPerLock = countPerLock;
            }
        }
        private class Node
        {
            internal TKey m_key;
            internal TValue m_value;
            internal volatile ConcurrentDictionary<TKey, TValue>.Node m_next;
            internal int m_hashcode;
            internal Node(TKey key, TValue value, int hashcode, ConcurrentDictionary<TKey, TValue>.Node next)
            {
                this.m_key = key;
                this.m_value = value;
                this.m_next = next;
                this.m_hashcode = hashcode;
            }
        }
        private class DictionaryEnumerator : IDictionaryEnumerator, IEnumerator
        {
            private IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator;
            public DictionaryEntry Entry
            {
                get
                {
                    KeyValuePair<TKey, TValue> current = this.m_enumerator.Current;
                    object arg_30_0 = current.Key;
                    KeyValuePair<TKey, TValue> current2 = this.m_enumerator.Current;
                    return new DictionaryEntry(arg_30_0, current2.Value);
                }
            }
            public object Key
            {
                get
                {
                    KeyValuePair<TKey, TValue> current = this.m_enumerator.Current;
                    return current.Key;
                }
            }
            public object Value
            {
                get
                {
                    KeyValuePair<TKey, TValue> current = this.m_enumerator.Current;
                    return current.Value;
                }
            }
            public object Current
            {
                get
                {
                    return this.Entry;
                }
            }
            internal DictionaryEnumerator(ConcurrentDictionary<TKey, TValue> dictionary)
            {
                this.m_enumerator = dictionary.GetEnumerator();
            }
            public bool MoveNext()
            {
                return this.m_enumerator.MoveNext();
            }
            public void Reset()
            {
                this.m_enumerator.Reset();
            }
        }
        [NonSerialized]
        private volatile ConcurrentDictionary<TKey, TValue>.Tables m_tables;
        private readonly IEqualityComparer<TKey> m_comparer;
        [NonSerialized]
        private readonly bool m_growLockArray;
        [NonSerialized]
        private int m_budget;
        private KeyValuePair<TKey, TValue>[] m_serializationArray;
        private int m_serializationConcurrencyLevel;
        private int m_serializationCapacity;
        private static readonly bool s_isValueWriteAtomic = ConcurrentDictionary<TKey, TValue>.IsValueWriteAtomic();
        private const int DEFAULT_CONCURRENCY_MULTIPLIER = 4;
        private const int DEFAULT_CAPACITY = 31;
        private const int MAX_LOCK_NUMBER = 1024;
        /// <summary>Gets or sets the value associated with the specified key.</summary>
        /// <returns>Returns the Value property of the <see cref="T:System.Collections.Generic.KeyValuePair`2" /> at the specified index.</returns>
        /// <param name="key">The key of the value to get or set.</param>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="key" /> is a null reference (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">The property is retrieved and <paramref name="key" /> does not exist in the collection.</exception>
        [__DynamicallyInvokable]
        public TValue this[TKey key]
        {
            [__DynamicallyInvokable]
            get
            {
                TValue result;
                if (!this.TryGetValue(key, out result))
                {
                    throw new KeyNotFoundException();
                }
                return result;
            }
            [__DynamicallyInvokable]
            set
            {
                if (key == null)
                {
                    throw new ArgumentNullException("key");
                }
                TValue tValue;
                this.TryAddInternal(key, value, true, true, out tValue);
            }
        }
        /// <summary>Gets the number of key/value pairs contained in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</summary>
        /// <returns>The number of key/value pairs contained in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</returns>
        /// <exception cref="T:System.OverflowException">The dictionary already contains the maximum number of elements, <see cref="F:System.Int32.MaxValue" />.</exception>
        [__DynamicallyInvokable]
        public int Count
        {
            [__DynamicallyInvokable]
            get
            {
                int num = 0;
                int toExclusive = 0;
                try
                {
                    this.AcquireAllLocks(ref toExclusive);
                    for (int i = 0; i < this.m_tables.m_countPerLock.Length; i++)
                    {
                        num += this.m_tables.m_countPerLock[i];
                    }
                }
                finally
                {
                    this.ReleaseLocks(0, toExclusive);
                }
                return num;
            }
        }
        /// <summary>Gets a value that indicates whether the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> is empty.</summary>
        /// <returns>true if the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> is empty; otherwise, false.</returns>
        [__DynamicallyInvokable]
        public bool IsEmpty
        {
            [__DynamicallyInvokable]
            get
            {
                int toExclusive = 0;
                try
                {
                    this.AcquireAllLocks(ref toExclusive);
                    for (int i = 0; i < this.m_tables.m_countPerLock.Length; i++)
                    {
                        if (this.m_tables.m_countPerLock[i] != 0)
                        {
                            return false;
                        }
                    }
                }
                finally
                {
                    this.ReleaseLocks(0, toExclusive);
                }
                return true;
            }
        }
        /// <summary>Gets a collection containing the keys in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</summary>
        /// <returns>An <see cref="T:System.Collections.Generic.ICollection{TKey}" /> containing the keys in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</returns>
        [__DynamicallyInvokable]
        public ICollection<TKey> Keys
        {
            [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
            get
            {
                return this.GetKeys();
            }
        }
        /// <summary>Gets a collection containing the values in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</summary>
        /// <returns>An <see cref="T:System.Collections.Generic.ICollection{TValue}" /> containing the values in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}" />.</returns>
        [__DynamicallyInvokable]
        public ICollection<TValue> Values
        {
            [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
            get
            {
                return this.GetValues();
            }
        }
        [__DynamicallyInvokable]
        bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
        {
            [__DynamicallyInvokable]
            get
            {
                return false;
            }
        }
        /// <summary>Gets a value indicating whether the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> has a fixed size.</summary>
        /// <returns>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> has a fixed size; otherwise, false. For <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns>
        [__DynamicallyInvokable]
        bool IDictionary.IsFixedSize
        {
            [__DynamicallyInvokable]
            get
            {
                return false;
            }
        }
        /// <summary>Gets a value indicating whether the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> is read-only.</summary>
        /// <returns>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" /> is read-only; otherwise, false. For <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns>
        [__DynamicallyInvokable]
        bool IDictionary.IsReadOnly
        {
            [__DynamicallyInvokable]
            get
            {
                return false;
            }
        }
        /// <summary>Gets an <see cref="T:System.Collections.ICollection" /> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" />.</summary>
        /// <returns>An <see cref="T:System.Collections.ICollection" /> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}" />.</returns>
        [__DynamicallyInvokable]
        ICollection IDictionary.Keys
        {
            [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
            get
            {
                return this.GetKeys();
            }
        }
        /// <summary>Gets an <see cref="T:System.Collections.ICollection" /> containing the values in the <see cref="T:System.Collections.IDictionary" />.</summary>
        /// <returns>An <see cref="T:System.Collections.ICollection" /> containing the values in the <see cref="T:System.Collections.IDictionary" />.</returns>
        [__DynamicallyInvokable]
        ICollection IDictionary.Values
        {
            [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
            get
            {
                return this.GetValues();
            }
        }
        /// <summary>Gets or sets the value associated with the specified key.</summary>
        /// <returns>The value associated with the specified key, or a null reference (Nothing in Visual Basic) if <paramref name="key" /> is not in the dictionary or <paramref name="key" /> is of a type that is not assignable to the key type  of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />.</returns>
        /// <param name="key">The key of the value to get or set.</param>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="key" /> is a null reference (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException">A value is being assigned, and <paramref name="key" /> is of a type that is not assignable to the key type  of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" />. -or- A value is being assigned, and <paramref name="key" /> is of a type that is not assignable to the value type  of the <see cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}" /></exception>
        [__DynamicallyInvokable]
        object IDictionary.this[object key]
        {
            [__DynamicallyInvokable]
            get
            {
                if (key == null)
                {
                    throw new ArgumentNullException("key");
                }
                TValue tValue;
                if (key is TKey && this.TryGetValue((TKey)((object)key), out tValue))
                {
                    return tValue;
                }
                return null;
            }
            [__DynamicallyInvokable]
            set
            {
                if (key == null)
                {
                    throw new ArgumentNullException("key");
                }
                if (!(key is TKey))
                {
                    throw new ArgumentException(this.GetResource("ConcurrentDictionary_TypeOfKeyIncorrect"));
                }
                if (!(value is TValue))
                {
                    throw new ArgumentException(this.GetResource("ConcurrentDictionary_TypeOfValueIncorrect"));
                }
                this[(TKey)((object)key)] = (TValue)((object)value);
            }
        }
        /// <summary>Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection" /> is synchronized with the SyncRoot.</summary>
        /// <returns>true if access to the <see cref="T:System.Collections.ICollection" /> is synchronized (thread safe); otherwise, false. For <see cref="T:System.Collections.Concurrent.ConcurrentDictionary{TKey,TValue}" />, this property always returns false.</returns>
        [__DynamicallyInvokable]
        bool ICollection.IsSynchronized
        {
            [__DynamicallyInvokable]
            get
            {
                return false;
            }
        }
        /// <summary>Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection" />. This property is not supported.</summary>
        /// <returns>Always returns null.</returns>
        /// <exception cref="T:System.NotSupportedException">The SyncRoot property is not supported.</exception>
        [__DynamicallyInvokable]
        object ICollection.SyncRoot
        {
            [__DynamicallyInvokable]
            get
            {
                throw new NotSupportedException("ConcurrentCollection_SyncRoot_NotSupported");
            }
        }
        private static int DefaultConcurrencyLevel
        {
            get
            {
                return 4 * PlatformHelper.ProcessorCount;
            }
        }
        private static bool IsValueWriteAtomic()
        {
            Type typeFromHandle = typeof(TValue);
            bool flag = typeFromHandle.IsClass || typeFromHandle == typeof(bool) || typeFromHandle == typeof(char) || typeFromHandle == typeof(byte) || typeFromHandle == typeof(sbyte) || typeFromHandle == typeof(short) || typeFromHandle == typeof(ushort) || typeFromHandle == typeof(int) || typeFromHandle == typeof(uint) || typeFromHandle == typeof(float);
            if (!flag && IntPtr.Size == 8)
            {
                flag |= (typeFromHandle == typeof(double) || typeFromHandle == typeof(long));
            }
            return flag;
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the default concurrency level, has the default initial capacity, and uses the default comparer for the key type.</summary>
        [__DynamicallyInvokable]
        public ConcurrentDictionary()
            : this(ConcurrentDictionary<TKey, TValue>.DefaultConcurrencyLevel, 31, true, EqualityComparer<TKey>.Default)
        {
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the specified concurrency level and capacity, and uses the default comparer for the key type.</summary>
        /// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param>
        /// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> can contain.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        ///   <paramref name="concurrencyLevel" /> is less than 1.-or-<paramref name="capacity" /> is less than 0.</exception>
        [__DynamicallyInvokable]
        public ConcurrentDictionary(int concurrencyLevel, int capacity)
            : this(concurrencyLevel, capacity, false, EqualityComparer<TKey>.Default)
        {
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" />, has the default concurrency level, has the default initial capacity, and uses the default comparer for the key type.</summary>
        /// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="collection" /> or any of its keys is a null reference (Nothing in Visual Basic)</exception>
        /// <exception cref="T:System.ArgumentException">
        ///   <paramref name="collection" /> contains one or more duplicate keys.</exception>
        [__DynamicallyInvokable]
        public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection)
            : this(collection, EqualityComparer<TKey>.Default)
        {
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the default concurrency level and capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception>
        [__DynamicallyInvokable]
        public ConcurrentDictionary(IEqualityComparer<TKey> comparer)
            : this(ConcurrentDictionary<TKey, TValue>.DefaultConcurrencyLevel, 31, true, comparer)
        {
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable" />, has the default concurrency level, has the default initial capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary>
        /// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="collection" /> is a null reference (Nothing in Visual Basic). -or- <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception>
        [__DynamicallyInvokable]
        public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
            : this(comparer)
        {
            if (collection == null)
            {
                throw new ArgumentNullException("collection");
            }
            this.InitializeFromCollection(collection);
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable" />, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary>
        /// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param>
        /// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}" /> whose elements are copied to the new <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</param>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="collection" /> is a null reference (Nothing in Visual Basic). -or- <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        ///   <paramref name="concurrencyLevel" /> is less than 1.</exception>
        /// <exception cref="T:System.ArgumentException">
        ///   <paramref name="collection" /> contains one or more duplicate keys.</exception>
        [__DynamicallyInvokable]
        public ConcurrentDictionary(int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
            : this(concurrencyLevel, 31, false, comparer)
        {
            if (collection == null)
            {
                throw new ArgumentNullException("collection");
            }
            if (comparer == null)
            {
                throw new ArgumentNullException("comparer");
            }
            this.InitializeFromCollection(collection);
        }
        private void InitializeFromCollection(IEnumerable<KeyValuePair<TKey, TValue>> collection)
        {
            foreach (KeyValuePair<TKey, TValue> current in collection)
            {
                if (current.Key == null)
                {
                    throw new ArgumentNullException("key");
                }
                TValue tValue;
                if (!this.TryAddInternal(current.Key, current.Value, false, false, out tValue))
                {
                    throw new ArgumentException(this.GetResource("ConcurrentDictionary_SourceContainsDuplicateKeys"));
                }
            }
            if (this.m_budget == 0)
            {
                this.m_budget = this.m_tables.m_buckets.Length / this.m_tables.m_locks.Length;
            }
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> class that is empty, has the specified concurrency level, has the specified initial capacity, and uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" />.</summary>
        /// <param name="concurrencyLevel">The estimated number of threads that will update the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> concurrently.</param>
        /// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> can contain.</param>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}" /> implementation to use when comparing keys.</param>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="comparer" /> is a null reference (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        ///   <paramref name="concurrencyLevel" /> is less than 1. -or- <paramref name="capacity" /> is less than 0.</exception>
        [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        public ConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer)
            : this(concurrencyLevel, capacity, false, comparer)
        {
        }
        internal ConcurrentDictionary(int concurrencyLevel, int capacity, bool growLockArray, IEqualityComparer<TKey> comparer)
        {
            if (concurrencyLevel < 1)
            {
                throw new ArgumentOutOfRangeException("concurrencyLevel", this.GetResource("ConcurrentDictionary_ConcurrencyLevelMustBePositive"));
            }
            if (capacity < 0)
            {
                throw new ArgumentOutOfRangeException("capacity", this.GetResource("ConcurrentDictionary_CapacityMustNotBeNegative"));
            }
            if (comparer == null)
            {
                throw new ArgumentNullException("comparer");
            }
            if (capacity < concurrencyLevel)
            {
                capacity = concurrencyLevel;
            }
            object[] array = new object[concurrencyLevel];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = new object();
            }
            int[] countPerLock = new int[array.Length];
            ConcurrentDictionary<TKey, TValue>.Node[] array2 = new ConcurrentDictionary<TKey, TValue>.Node[capacity];
            this.m_tables = new ConcurrentDictionary<TKey, TValue>.Tables(array2, array, countPerLock);
            this.m_comparer = comparer;
            this.m_growLockArray = growLockArray;
            this.m_budget = array2.Length / array.Length;
        }
        /// <summary>Attempts to add the specified key and value to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" />.</summary>
        /// <returns>true if the key/value pair was added to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> successfully. If the key already exists, this method returns false.</returns>
        /// <param name="key">The key of the element to add.</param>
        /// <param name="value">The value of the element to add. The value can be a null reference (Nothing in Visual Basic) for reference types.</param>
        /// <exception cref="T:System.ArgumentNullException">
        ///   <paramref name="key" /> is null reference (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.OverflowException">The dictionary already contains the maximum number of elements, <see cref="F:System.Int32.MaxValue" />.</exception>
        [__DynamicallyInvokable]
        public bool TryAdd(TKey key, TValue value)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            TValue tValue;

Lines 1–500 of 1413.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t