Proper way to initialize a C# dictionary with values
I can't reproduce this issue in a simple .NET 4.0 console application:
static class Program
{
static void Main(string[] args)
{
var myDict = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" }
};
Console.ReadKey();
}
}
Can you try to reproduce it in a simple Console application and go from there? It seems likely that you're targeting .NET 2.0 (which doesn't support it) or client profile framework, rather than a version of .NET that supports initialization syntax.
Initialize a Dictionary with values in C# 2.0
But it doesn't work in C# 2.0. Is there any workaround for this without using Add or basing on an already existing collection?
No. The closest I can think of would be to write your own DictionaryBuilder
type to make it simpler:
public class DictionaryBuilder<TKey, TValue>
{
private Dictionary<TKey, TValue> dictionary
= new Dictionary<TKey, TValue> dictionary();
public DictionaryBuilder<TKey, TValue> Add(TKey key, TValue value)
{
if (dictionary == null)
{
throw new InvalidOperationException("Can't add after building");
}
dictionary.Add(key, value);
return this;
}
public Dictionary<TKey, TValue> Build()
{
Dictionary<TKey, TValue> ret = dictionary;
dictionary = null;
return ret;
}
}
Then you can use:
Dictionary<string, int> x = new DictionaryBuilder<string, int>()
.Add("Foo", 10)
.Add("Bar", 20)
.Build();
This is at least a single expression still, which is useful for fields where you want to initialize at the point of declaration.
How to insert values into C# Dictionary on instantiation?
There's whole page about how to do that here:
http://msdn.microsoft.com/en-us/library/bb531208.aspx
Example:
In the following code example, a
Dictionary<TKey, TValue>
is
initialized with instances of typeStudentName
:
var students = new Dictionary<int, StudentName>()
{
{ 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
{ 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
{ 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
};
Adding values to a dictionary via inline initialization of its container
AllCities.Add(new City("Rome") { Names = { { "DE", "Rom" }, { "...", "..." } } });
This is using initializer syntax to invoke the .Add method.
C# How does Dictionary work when we initialize a class within as a value?
Does the compiler first creates a constructor (parameterless ctor) and only then add my KeyValuePairs?
The compiler doesn't have to create anything. Dictionary<>
has a parameterless constructor, which you're calling here:
new Dictionary<string, ViewModelBase>();
You're simply invoking the constructor, passing no parameters, and getting back an instance of a Dictionary<string, ViewModelBase>
.
When I add my KeyValuePairs, are the Values also instantiated?
They're instantiated, because you're instantiating them:
new LoginViewModel()
Like any other constructor, this creates a new instance of the class.
Note that none of the code you're showing really has anything to do with class initializers. An initializer for a collection type (like a Dictionary<>
) might look something like this:
Dictionary<string, ViewModelBase> tempDictionary = new Dictionary<string, ViewModelBase>() {
{"LoginView", new LoginViewModel()},
{"SignUpView", new SignUpViewModel()},
{"ContactListView", new ContactListViewModel()}
}
Which is compiled to essentially the equivalent of what you have:
Dictionary<string, ViewModelBase> tempDictionary = new Dictionary<string, ViewModelBase>();
tempDictionary.Add("LoginView", new LoginViewModel());
tempDictionary.Add("SignUpView", new SignUpViewModel());
tempDictionary.Add("ContactListView", new ContactListViewModel());
It's not entirely clear where your confusion is on the subject, but essentially all any of this code does is create instances of objects.
Initialize a Dictionary with arrays of keys and values
Use Zip()
:
int[] keys = { 1, 2, 3 };
string[] values = { "a", "b", "c" };
var dict = keys.Zip(values, (num, str) => new { num = num, str = str })
.ToDictionary(ns => ns.num, ns => ns.str);
It won't be faster, and for all I know it might actually be a little slower, though probably not by enough to matter.
The one clear advantage it has over your for
loop is that Zip()
won't throw an exception if values.Length < keys.Length
.
Once the C#7 value tuple feature is usable without any nonsense, you'll be able to save a few characters:
var dict = keys.Zip(values, (num, str) => (num: num, str: str))
.ToDictionary(ns => ns.num, ns => ns.str);
How to initialize DictionaryT, ListU with data
Your doing two things at once. The right hand side of your expression looks like:
new Dictionary<string, List<string>>().Add("some key",new List<string> {"some string"});
You are creating a dictionary, and immediately adding an item to it. Add
returns void, so you aren't going to be able to capture the reference to your dictionary this way. You want to first assign your dictionary to a variable, then add to it.
Or even better, you can use a collection initializer, like you are already doing with your List
var dicData = new Dictionary<string, List<string>>
{
["some key"] = new List<string> { "some string"}
};
The above code uses C#6 syntax
How to initialize an dictionary with an array value?
This works for me (surrounding with another set of {}
- for the KeyValuePair
that you create) so it doesn't find the function you are trying to execute:
Dictionary<string, string[]> dict = new Dictionary<string, string[]>
{
{ "key1", new [] { "value", "another value", "and another" } },
{ "key2", new [] { "value2", "another value", "and another" } }
};
I'd suggest to follow C# {}
conventions - good indentation helps to find these problems easily :)
Related Topics
Capturing Binary Output from Process.Standardoutput
Equivalent of SQL Isnull in Linq
Should I Store My Images in the Database or Folders
What's the Difference Between Returning Void and Returning a Task
How to Discover the "Path" of an Embedded Resource
How to Monitor Clipboard Content Changes in C#
Entity Framework/Sql2008 - How to Automatically Update Lastmodified Fields for Entities
Gui and Windows Service Communication
Loading a Full Hierarchy from a Self Referencing Table with Entityframework.Core
How to Print the Contents of an Array Horizontally
Open Default Mail Client Along with a Attachment
Server Execution Failed (Exception from Hresult: 0X80080005 (Co_E_Server_Exec_Failure))
Print Webbrowser Without Previewing I.E. Single Click Print
Why Use Try {} Finally {} with an Empty Try Block
Detecting Network Connection Speed and Bandwidth Usage in C#