How to initialize a ConcurrentDictionary? Error: "Unable to access the private method" Add "here"

I have a static class in which I use dictionaries as lookup tables to map between .NET types and SQL types. Here is an example of such a dictionary:

private static readonly Dictionary<Type, string> SqlServerMap = new Dictionary<Type, string> { {typeof (Boolean), "bit"}, {typeof (Byte[]), "varbinary(max)"}, {typeof (Double), "float"}, {typeof (Byte), "tinyint"}, {typeof (Int16), "smallint"}, {typeof (Int32), "int"}, {typeof (Int64), "bigint"}, {typeof (Decimal), "decimal"}, {typeof (Single), "real"}, {typeof (DateTime), "datetime2(7)"}, {typeof (TimeSpan), "time"}, {typeof (String), "nvarchar(MAX)"}, {typeof (Guid), "uniqueidentifier"} }; 

Then I have a public method that runs in a .NET type, and it returns the string value of the corresponding MS SQL Server type using this dictionary. However, since it is used as a lookup table to create database queries, I think it makes sense to do this ConcurrentDictionary. I changed it to:

 private static readonly IDictionary<Type, string> SqlServerMap = new ConcurrentDictionary<Type, string> { {typeof (Boolean), "bit"}, {typeof (Byte[]), "varbinary(max)"}, {typeof (Double), "float"}, {typeof (Byte), "tinyint"}, {typeof (Int16), "smallint"}, {typeof (Int32), "int"}, {typeof (Int64), "bigint"}, {typeof (Decimal), "decimal"}, {typeof (Single), "real"}, {typeof (DateTime), "datetime2(7)"}, {typeof (TimeSpan), "time"}, {typeof (String), "nvarchar(MAX)"}, {typeof (Guid), "uniqueidentifier"} }; 

But now it underlines everything in red inside {} (that is, all pairs of ConcurrentDictionary key values), and the error: β€œUnable to access the private Add method here. I don’t think this is because I initialize it as closed static readonly because I just tested by creating a public static version and I get the same error.

+7
dictionary private c # concurrentdictionary idictionary
source share
4 answers

The collection initializer that you use to populate the collection only works if the collection has the Add method with the appropriate signature and availability. ConcurrentDictionary does not have a public Add method, so you cannot use the collection initializer with it.

You can provide some source data by passing IEnumerable<KeyValuePair<TKey, TValue>> as a parameter to the constructor, or you can call TryAdd (or AddOrUpdate or any of the other methods with Add in the name) in a loop after creating ConcurrentDictionary .

+11
source share

try it

 private static readonly IDictionary<Type, string> SqlServerMap = new ConcurrentDictionary<Type, string>(new Dictionary<Type, string>() { {typeof (Boolean), "bit"}, {typeof (Byte[]), "varbinary(max)"}, {typeof (Double), "float"}, {typeof (Byte), "tinyint"}, {typeof (Int16), "smallint"}, {typeof (Int32), "int"}, {typeof (Int64), "bigint"}, {typeof (Decimal), "decimal"}, {typeof (Single), "real"}, {typeof (DateTime), "datetime2(7)"}, {typeof (TimeSpan), "time"}, {typeof (String), "nvarchar(MAX)"}, {typeof (Guid), "uniqueidentifier"} }); 
+5
source share

As @Servy said in his answer, collection initialization works for types with the Add method. But it should also work if there is an extension method with the name Add and the corresponding signature. This way you can create one for a parallel dictionary. Initialization will be thread safe since you are using a static field initializer.

0
source share

As an example of the code for the accepted Servy answer, to initialize the ConcurrentDictionary when creating the instance, you can pass the type that is assigned to the IEnumerable (e.g. List )) KeyValuePair :

 private static readonly IDictionary<Type, string> SqlServerMap = new ConcurrentDictionary<Type, string>( new List<KeyValuePair<Type, string>> { new KeyValuePair<Type, string>(typeof(Boolean), "bit"), new KeyValuePair<Type, string>(typeof(Boolean), "bit"), new KeyValuePair<Type, string>(typeof(Byte[]), "varbinary(max)"), new KeyValuePair<Type, string>(typeof(Double), "float"), new KeyValuePair<Type, string>(typeof(Byte), "tinyint"), new KeyValuePair<Type, string>(typeof(Int16), "smallint"), new KeyValuePair<Type, string>(typeof(Int32), "int"), new KeyValuePair<Type, string>(typeof(Int64), "bigint"), new KeyValuePair<Type, string>(typeof(Decimal), "decimal"), new KeyValuePair<Type, string>(typeof(Single), "real"), new KeyValuePair<Type, string>(typeof(DateTime), "datetime2(7)"), new KeyValuePair<Type, string>(typeof(TimeSpan), "time"), new KeyValuePair<Type, string>(typeof(String), "nvarchar(MAX)"), new KeyValuePair<Type, string>(typeof(Guid), "uniqueidentifier") }); 
0
source share

All Articles