I have my Dictionary declared like this:
private static Dictionary<string, Dictionary<string, string>> myDictionary;
I want to initialize it globally. The closest I have come initializes the outer Dictionary, but still leaves me with a null reference to the inner Dictionary:
private static Dictionary<string, Dictionary<string, string>> myDictionary
= new Dictionary<string, Dictionary<string, string>>();
I need to avoid initializing it in a method, because I don't want to force the user to call a method before being able to use my class. The user only has access to static methods. I could create a singleton when they call one of the methods, but that's dirty.
How can I declare both dictionaries globally? Something along the lines of one of these (although neither compile):
private static Dictionary<string, Dictionary<string, string>> myDictionary
= new Dictionary<string, new Dictionary<string, string>>();
or
private static Dictionary<string, string> inner = new Dictionary<string, string>();
private static Dictionary<string, Dictionary<string, string>> myDictionary
= new Dictionary<string, inner>();
Use the static constructor like this (assuming that the myDictionary variable is in a class called MyClass) :
public class MyClass
{
private static Dictionary<string, Dictionary<string, string>> myDictionary;
static MyClass()
{
//Initialize static members here
myDictionary = new Dictionary<string, Dictionary<string, string>>();
myDictionary.Add("mykey", new Dictionary<string, string>());
...
}
}
The framework will make sure that the static constructor is automatically executed before you access any member of the class.
You can initialize it inline without doing it in a method by following the {} collection initialization syntax:
private static Dictionary<string, Dictionary<string, string>> = new Dictionary<string, Dictionary<string, string>> {
{ "first"
, new Dictionary<string, string> {
{"A", "one"}
, {"B", "two"}
}
}
, { "second"
, new Dictionary<string, string> {
{"Y", "twenty five"}
, {"Z", "twenty six"}
}
}
}
Related
I have a class, with some global and constant dictionaries. Like:
public static class Constants
{
public static Dictionary<string, MyObject> MyDictionary= new Dictionary<string, MyObject>()
{
{"first", new MyObject()},
{"second", new MyObject()},
};
}
Lets say I would like another dictionary, to be like that only with some added and removed elements. Is there a way to achieve that, within the static class? I imagine something like:
public static Dictionary<string, MyObject> MyOtherDictionary = MyDictionary.Remove("second").Add("Third", new MyObject())
But I know that does not work, so is there any way I can achieve this?
No, that doesnt work in this way for two reasons:
Remove returns a bool, you can't use Add on a bool
even if you make it compile, you don't want to modify the other dictionary but you want to create a new dictionary which contains similar items, you can use the constructor:
public static Dictionary<string, MyObject> MyOtherDictionary;
// ...
static Constants
{
MyOtherDictionary = new Dictionary<string, MyObject>(MyDictionary);
MyOtherDictionary.Remove("second");
MyOtherDictionary.Add("Third", new MyObject());
}
You could do it using properties instead
public static class Constants
{
public static Dictionary<string, MyObject> myDictionary
{
get
{
return new Dictionary<string, MyObject>()
{
{ "first", new MyObject()},
{ "second", new MyObject()},
};
}
}
static Dictionary<string, MyObject> _myOtherDictionary;
public static Dictionary<string, MyObject> myOtherDictionary
{
get
{
_myOtherDictionary = myDictionary;
_myOtherDictionary.Remove("first");
_myOtherDictionary.Add("third", new MyObject());
return _myOtherDictionary;
}
}
}
I have a static class to hold a dictionary and 2 get methods to access it
Here is my class:
public static class ConfiguraCuadros
{
public static Dictionary<string,Dictionary<string,Dictionary<string,Dictionary<string,string>>>> GetDictionary()
{
// Try to get the result in the static Dictionary
return _configcuadros;
}
public static Dictionary<string, Dictionary<string, Dictionary<string, string>>> GetHoja(string key)
{
// Try to get the result in the static Dictionary
Dictionary<string, Dictionary<string, Dictionary<string, string>>> result = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
if (_configcuadros.TryGetValue(key, out result))
{
return result;
}
else
{
return null;
}
}
public static readonly Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> _configcuadros = new Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>>
{
{ "Formato01", //this is just a hint, the dictionary is much more extensive
new Dictionary<string, Dictionary<string, Dictionary<string, string>>>
{
{
"F01C01A",
new Dictionary<string, Dictionary<string, string>>
{
{
"X",
new Dictionary<string, string>
{
{ "key1" , "value1" },
{ "key2" , "value2" },
{ "key3" , "value3" },
}
},
}
},
}
},
}
}`
When I use the getter method,
ConfiguraCuadros.GetDictionary();
It throws an exception:
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
'ConfiguraCuadros.GetDictionary()' threw an exception of type 'System.TypeInitializationException'
base: {"The type initializer for 'beDGRAIC.ConfiguraCuadros' threw an exception."}
TypeName: "beDGRAIC.ConfiguraCuadros"
or
'ConfiguraCuadros.GetHoja("Formato01")' threw an exception of type 'System.TypeInitializationException'
base: {"The type initializer for 'beDGRAIC.ConfiguraCuadros' threw an exception."}
TypeName: "beDGRAIC.ConfiguraCuadros"
As you can see, my intention is to have a static dictionary. I think the problem is in the dictionary declaration ... but I can't see where...
Just in case, "beDGRAIC" is my namespace.
Thanks for your help!
Your code works (almost) as is for me.
I just added a missing semi-colon to get it to compile but can then call ConfiguraCuadros.GetDictionary(); without any exception.
Here is the code back with that missing semicolon:
public static class ConfiguraCuadros
{
public static Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> GetDictionary()
{
// Try to get the result in the static Dictionary
return _configcuadros;
}
public static Dictionary<string, Dictionary<string, Dictionary<string, string>>> GetHoja(string key)
{
// Try to get the result in the static Dictionary
Dictionary<string, Dictionary<string, Dictionary<string, string>>> result = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
if (_configcuadros.TryGetValue(key, out result))
{
return result;
}
else
{
return null;
}
}
public static readonly Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> _configcuadros = new Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>>
{
{ "Formato01", //this is just a hint, the dictionary is much more extensive
new Dictionary<string, Dictionary<string, Dictionary<string, string>>>
{
{
"F01C01A",
new Dictionary<string, Dictionary<string, string>>
{
{
"X",
new Dictionary<string, string>
{
{ "key1" , "value1" },
{ "key2" , "value2" },
{ "key3" , "value3" },
}
},
}
}
}
}
};
}
[UPDATE]
I do agree with the comments above about checking out the InnerException as a general rule for a type initialisation exception and, particularly, about the unfriendly nature of the datatype!
What is wrong with my syntax? I want to be able to get the value "Genesis" with this info["Gen"]["name"]
public var info = new Dictionary<string, Dictionary<string, string>> {
{"Gen", new Dictionary<string, string> {
{"name", "Genesis"},
{"chapters", "50"},
{"before", ""},
{"after", "Exod"}
}},
{"Exod", new Dictionary<string, string> {
{"name", "Exodus"},
{"chapters", "40"},
{"before", "Gen"},
{"after", "Lev"}
}}};
You cannot define a class field using var.
Change var to Dictionary<string, Dictionary<string, string>>:
public Dictionary<string, Dictionary<string, string>> info =
new Dictionary<string, Dictionary<string, string>>
{
{
"Gen",
new Dictionary<string, string>
{
{"name", "Genesis"},
{"chapters", "50"},
{"before", ""},
{"after", "Exod"}
}
},
{
"Exod",
new Dictionary<string, string>
{
{"name", "Exodus"},
{"chapters", "40"},
{"before", "Gen"},
{"after", "Lev"}
}
}
};
See here for more information about var keyword and its usage.
From MSDN;
var can only be used when a local variable is declared and initialized
in the same statement; the variable cannot be initialized to null, or
to a method group or an anonymous function.
var cannot be used on fields at class scope.
Variables declared by using var cannot be used in the initialization
expression.
Just change your var to Dictionary<string, Dictionary<string, string>>. Like;
public Dictionary<string, Dictionary<string, string>> info =
new Dictionary<string, Dictionary<string, string>>{}
I have create a Class named "EngDictionary". and Then i define a dictionary in a function
e.g:
public void Dict()
{
Dictionary<string, string> d = new Dictionary<string, string>();
d.Add("Classifieds", "Kleinanzeigen");
//d.Add("windows", 5);
}
Now i want to access above defined dictionary from my main class for retrieving the keys and values of my Dictionary. Please Suggest me some code. I am using Visual C# 2008 Express Edition, Win Application
Declare Dictionary as class property.
public class Dict {
private Dictionary<string, string> dict;
public SomeDictionary { get dict; set dict = value; }
public Dict() {
dict = new Dictionary<string, string>();
dict.Add("Classifieds", "Kleinanzeigen");
}
}
In other class:
Dict d = new Dict();
string test = d.SomeDictionary["Classifieds"];
Console.WriteLine(test);
return the dictionary from the method.
public Dictionary<string, string> Dict() {.... ; return d;}
In your main class.
EngDictionary dict = new EngDictionary();
Dictionary<string, string> dictionary = dict.Dict();
You can declare Dictionary<string, string> d as a member variable of your class , and initialize this object in the class constructor.You can have a getter method to get the dictionary in other classes.
public class EngDictionary
{
Dictionary<string, string> dictionary;
public void EngDictionary()
{
dictionary = new Dictionary<string, string>();
dictionary.Add("Classifieds", "Kleinanzeigen");
....
}
public Dictionary<string, string> getDictionary()
{
return this.dictionary;
}
}
I have a class
public class Dict
{
public Dictionary<string, string> SomeDictionary { get; } = new Dictionary<string, string>()
{
{ "Classifieds", "Kleinanzeigen" }
};
}
then in any other class
Dict Dic = new Dict();
foreach (var item in Dic.SomeDictionary)
{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
}
As i know, the method to add values for dictionary as below.
Dictionary<string, string> myDict = new Dictionary<string, string>();
myDict.Add("a", "1");
If I declared "myDictDict" as the style below.
IDictionary<string, Dictionary<string, string>> myDictDict = new Dictionary<string, Dictionary<string, string>>();
myDictDict .Add("hello", "tom","cat"); ?// How to add value here.
thank you.
The proper way is like this:
// myDictDict is Dictionary<string, Dictionary<string, string>>
Dictionary<string, string> myDict;
string key = "hello";
if (!myDictDict.TryGetValue(key, out myDict)) {
myDict = new Dictionary<string, string>();
myDictDict.Add(key, myDict);
}
myDict.Add("tom", "cat");
This will extract the dictionary corresponding to the key (hello in your example) or create it if necessary and then will add the key/value pair to that dictionary. You could even extract this into an extension method.
static class Extensions {
public static void AddToNestedDictionary<TKey, TNestedDictionary, TNestedKey, TNestedValue>(
this IDictionary<TKey, TNestedDictionary> dictionary,
TKey key,
TNestedKey nestedKey,
TNestedValue nestedValue
) where TNestedDictionary : IDictionary<TNestedKey, TNestedValue> {
dictionary.AddToNestedDictionary(
key,
nestedKey,
nestedValue,
() => (TNestedDictionary)(IDictionary<TNestedKey, TNestedValue>)
new Dictionary<TNestedKey, TNestedValue>());
}
public static void AddToNestedDictionary<TKey, TNestedDictionary, TNestedKey, TNestedValue>(
this IDictionary<TKey, TNestedDictionary> dictionary,
TKey key,
TNestedKey nestedKey,
TNestedValue nestedValue,
Func<TNestedDictionary> provider
) where TNestedDictionary : IDictionary<TNestedKey, TNestedValue> {
TNestedDictionary nested;
if (!dictionary.TryGetValue(key, out nested)) {
nested = provider();
dictionary.Add(key, nested);
}
nested.Add(nestedKey, nestedValue);
}
}
I left out guarding against null input to keep the idea clear.
Usage:
myDictDict.AddToNestedDictionary(
"hello",
"tom",
"cat",
() => new Dictionary<string, string>()
);
or
myDictDict.AddToNesteDictionary("hello", "tom", "cat");
IDictionary<string,Dictionary<string,string>> myDictDict = new Dictionary<string,Dictionary<string,string>>();
Dictionary<string,string> dict = new Dictionary<string, string>();
dict.Add ("tom", "cat");
myDictDict.Add ("hello", dict);
You can use C# 3's collection initializers, like this:
IDictionary<string, Dictionary<string, string>> myDictDict = new Dictionary<string, Dictionary<string, string>> {
{ "hello", new Dictionary<string, string> { "Tom", "Cat" } }
};
If the dictionary already exists, you can write
dict.Add("hello", new Dictionary<string, string> { "Tom", "Cat" });
Note that this will only work if hello isn't an existing key in the outer dictionary. If it might be, you should use Jason's answer.
To handle this the "simple" way : something like this :
myDictDict.Add("some string", new Dictionary<string, string>());
myDictDict["some string"].Add("another", "string");
To respond directly to the OP's test case : (note the edit added below reflects a desire to correct the syntax of SLaks's answer : code tested and validated against Framework 3.5 Client profile in VS 2010 Beta 2)
// a simple case of creating an instance of a dictionary
// of type <string, string>
// and using .NET 3.0's (FrameWork => 3.5) collection initializer syntax
Dictionary<string, string> twoStringDict = new Dictionary<string, string>()
{
{"key one", "value one"},
{"key two", "value two"}, // note : an "extra" comma does not cause an error here
};
// more complex case as in the question on StackOverFlow
// where dictionary is type <string, Dictionary<string, string>>
// and using .NET 3.0's (FrameWork => 3.5) collection initializer syntax
Dictionary<string, Dictionary<string, string>> myDictDict = new Dictionary<string, Dictionary<string, string>>()
{
{ "key one",
new Dictionary<string, string>() { { "innerKeyOne", "innerValueOne" }}},
{ "key two",
new Dictionary<string, string>() { { "innerKeyTwo", "innerValueTwo" }}}
};
// syntax for adding another key value pair to the complex case
myDictDict.Add("key three", new Dictionary<string, string>() { { "innerKeyThree", "innerValueThree" }});
IDictionary<string, Dictionary<string, string>> myDictDict = new Dictionary<string, Dictionary<string, string>>();
var subDict = new Dictionary<string, string>();
myDictDict .Add("hello", subDict );
subDict.Add("tom", "cat");
You can define an extension method like this :
static void Add(this IDictionary<string, Dictionary<string, string>> dict, string a, string b, string c){
dict.Add(a, new Dictionary<string,string>(){{b,c}};
}
and then use it as :
myDictDict.Add("hello", "tom","cat");