Today I saw C# code that creates static dictionary and initializes it:
public static readonly Dictionary<string, string> dict = new Dictionary<string, string>()
{
{"br","value1"},
{"cn","value2"},
{"de","value3"},
};
but when I decided to write same code for C++/CLI, an error occurred. Here is my attempt:
static System::Collections::Generic::Dictionary<System::String^, System::String^>^ dict = gcnew System::Collections::Generic::Dictionary<System::String^, System::String^>( )
{
{"br","value1"},
{"cn","value2"},
{"de","value3"},
};
Can I do this and if so, how?
C# 3.0 and later allows users to define an "initializer"; for collections, that's a series of elements, which for Dictionaries is streamlined to keys and values. C++.NET to my knowledge does not have this language feature. See this question: it's very similar: Array initialization in Managed C++. Array initializers are the ONLY such initializer in C++; other collections do not offer them in C++.
Basically, your main option is to declare a static constructor and initialize your dictionary in there.
This type of Dictionary<T>
initialization is a feature not of the class itself, but of the C# compiler. It translates it into separate statements for creation of the Dictionary<T>
object, and the creation and addition of each key/value pair. I don't believe the C++ compiler offers the same capabilities.
My approach is (.NET 4.5):
// file.h
using namespace System;
using namespace System::Collections::Generic;
// SomeClass
public://or private:
static Dictionary<String^, String^>^ dict = dictInitializer();
private:
static Dictionary<String^, String^>^ dictInitializer();
// file.cpp
#include "file.h"
Dictionary<String^, String^>^ SomeClass::dictInitializer(){
Dictionary<String^, String^>^ dict = gcnew Dictionary<String^, String^>;
dict->Add("br","value1");
dict->Add("cn","value2");
dict->Add("de","value3");
return dict;
}
It is possible! :-)
Not straight-forward, but with a tiny helper function you can create and init a dictionary in one line of code:
// helper class
generic <class TKey, class TValue>
ref class CDict
{
public:
static Dictionary<TKey, TValue>^ CreateDictionary (...array<KeyValuePair<TKey, TValue>>^ i_aValues)
{
Dictionary<TKey, TValue>^ dict = gcnew Dictionary<TKey, TValue>;
for (int ixCnt = 0; ixCnt < (i_aValues ? i_aValues->Length : 0); ixCnt++)
dict->Add (i_aValues[ixCnt].Key, i_aValues[ixCnt].Value);
return dict;
}
};
// Test
ref class CTest
{
public:
static Dictionary<int, String^>^ ms_dict = CDict<int, String^>::CreateDictionary (gcnew array<KeyValuePair<int, String^>>
{
KeyValuePair<int, String^>(1, "A"),
KeyValuePair<int, String^>(2, "B")
});
};
int main()
{
for each (KeyValuePair<int, String^> kvp in CTest::ms_dict)
Console::WriteLine (kvp.Key.ToString() + " " + kvp.Value);
}
Tested, working.