How can i make a dictionary inside a class in c#? - c#

hello i need to make a dictionary that is different for every istance of class for example
internal class items
{
Dictionary<string, string> items_property = new Dictionary<string, string>();
private string property1;
private string name_property1;
private string property2;
private string name_property2;
private string property3;
private string name_property3;
public items(Dictionary<string, string> items_property, string property1, string name_property1, string property2, string name_property2, string property3, string name_property3)
{
this.items_property = items_property;
this.property1 = property1;
this.name_property1 = name_property1;
this.property2 = property2;
this.name_property2 = name_property2;
this.property3 = property3;
this.name_property3 = name_property3;
items_property.Add(name_property1, property1);
items_property.Add(name_property2, property2);
items_property.Add(name_property3, property3);
}
}
i need a way to make something that create a key and a value for that key so the user can make multiple object and every object can have a Dictionary with different thing inside
example
obj car
key=speed value=100
key=price value=2000
obj dog
key=age value=5;
key=name value="doggo";

Is this what you're trying to achieve?
internal class Items
{
Dictionary<string, string> ItemsProperty = new Dictionary<string, string>();
public Items(Dictionary<string, string> itemsProperty)
{
ItemsProperty = itemsProperty;
}
}
If you create a variable of type Items called itemsObj, you could then access each property like itemsObj.ItemsProperty["speed"], itemsObj.ItemsProperty["age"], etc.

If only those making the class needs to know about what is in the dictionary then you need a generic class
internal class items<T>
{
Dictionary<string, T> items_property = new Dictionary<string, T>();

Related

Writing into nested Dictionary in Unity3D

Can I not write values into my nested dictionary directly?
It would be nice if I could access it like this:
public Dictionary<string, Dictionary<string, Dictionary<string, int>>> planets =
new Dictionary<string, Dictionary<string, Dictionary<string, int>>>();
planets[Planet.CharacterId]["MetalMine"]["Level"] = 0;
But I'm getting:
KeyNotFoundException: The given key was not present in the dictionary.
Does this mean I got to insert my Keys after each other?
Does this mean I got to insert my Keys after each other?
Yes, you need to initialize each in order:
planets[Planet.CharacterId] = new Dictionary<string, Dictionary<string, int>>();
planets[Planet.CharacterId]["MetalMine"] = new Dictionary<string, int>();
planets[Planet.CharacterId]["MetalMine"]["Level"] = 0;
You could use collection initializer syntax here, but that won't make stuff much more readable nor maintainable.
Instead of a dictionary of dicionaries of dictionaries you seem to be better off using a class:
public class Planet
{
public List<Mine> Mines { get; set; }
}
public class Mine
{
public string Type { get; set; }
public int Level { get; set; }
}
var planets = new Dictionary<string, Planet>();
planets[Planet.CharacterId] = new Planet
{
Mines = new List<Mine>
{
new Mine
{
Type = "Metal",
Level = 0
}
};
}
It's may be helpful or Nested dictionary alternative.
Create Sample.cs script and test it.
public Dictionary<string,Tuple<string,string,string,int>> _planets = new Dictionary<string, Tuple<string,string, string, int>>();
void Start()
{
string myKey = string.Concat("1","MetalMine","Level");
if(!_planets.ContainsKey(myKey))
{
_planets.Add(myKey,Tuple.Create("1","MetalMine","Level",0));
}
Debug.Log("_planets mykey "+myKey+" ==> "+_planets[myKey].Item4);
}

C# Calling a dictionary within an extension class?

Re-written everything exactly as my program has it:
class DictionaryInitializer
{
public class DictionarySetup
{
public string theDescription { get; set; }
public string theClass { get; set; }
}
public class DictionaryInit
{
//IS_Revenues data
public Dictionary<int, DictionarySetup> accountRevenue = new Dictionary<int, DictionarySetup>()
{
{ 400000, new DictionarySetup {theDescription="Call", theClass="Revenues"}},
{ 400001, new DictionarySetup {theDescription="Bill", theClass="Revenues"}},
{ 495003, new DictionarySetup {theDescription="Revenue", theClass="Revenues"}}
};
public Dictionary<int, DictionarySetup> accountExpenses = new Dictionary<int, DictionarySetup>()
{
{790130, new DictionarySetup { theDescription="Currency Hedge", theClass="Other income/expense"}},
{805520, new DictionarySetup { theDescription="Int Income", theClass="Other income/expense"}}
};
}
On my mainform:
DictionaryInit theDictionary;
btnClick() {
theDictionary = new DictionaryInit();
//Some code to loop through a datagridview
//Somemore Code
foreach (var item in theDictionary.accountRevenue)
{
int theKey = item.Key;
if (theKey == keyCode)
{
DictionarySetup theValues = item.Value;
DGVMain.Rows[rowindex].Cells[3].Value = theValues.theDescription;
DGVMain.Rows[rowindex].Cells[11].Value = theValues.theClass;
DGVMain.Rows[rowindex].Cells[12].Value = "Sale of Services";
Recording(rowindex);
}
}
}
Current work in progress:
DictionarySetup theValue;
if (theDictionary.accountExpenses.TryGetValue(keyCode,out theValue.theDescription) //[5]-> Account Type
{
//Some code to write dictionary data to the data grid view.
I'm working on making the TryGetValue and Contains(value) dictionary functions to work for now.
My current error messages are as follows:
"a property or indexer may not be passed as an out or ref parameter" when attempting the trygetvalue
and finally when trying the extension method i'm trying to create:
"Inconsistent accessibility, Dictionary<int, DictionaryInitializer.DictionarySetup> is less accessible than the method DictionaryUse<int, DictionaryInitializer.DictionarySetup>"
You have to make your field public....
Dictionary<int, DictionarySetup> accountRevenue
should be
public Dictionary<int, DictionarySetup> accountRevenue
if you want to refer to it from outside the class..
This part seems to also be missing a variable name;
public void DictionaryUse (int code, int key, Dictionary)
should be
public void DictionaryUse (int code, int key, Dictionary<int, DictionarySetup> theDictionary)
But I agree with the other comments, you seem to be re-inventing the wheel, just use the existing Dictionary utility methods

Converting an anonymous object's properties and values to a Dictionary

I am creating a library for an existing API. I currently have QueryParameter classes for each request class. The QueryParameter classes are simple but they do vary (not all requests take the same query parameters).
Here is an example of a QueryParameter class:
public class ApiRequestAQueryParameters
{
public string Name { get; set; }
public int Start { get; set; }
public int Stop { get; set; }
}
I am interested in a way to convert a class like this into a Dictionary that I can feed to our Web client. I am hoping to have a reusable method like:
private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
// perform conversion
}
This way I won't have to pull out the QueryParameter properties for each request (there will be dozens of requests)
The reason that I am using QueryParameter classes instead of making QueryParameter a Dictionary property of each API request class is to be developer friendly. I want to make it so that others can build these API requests by looking at the classes.
There are 2 ways: 1) use reflection and 2) serialize to json and back.
Here is the 1st method:
private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
var res = new Dictionary<string, string>();
var props = queryParametersObject.GetType().GetProperties();
foreach (var prop in props)
{
res[prop.Name] = prop.GetValue(queryParametersObject).ToString();
}
return res;
}
You can do something like this:
private Dictionary<string, string> GenerateQueryParameters(object queryParameters)
{
var startStop = new StartStop() { Start = queryParameters.Start, Stop = queryParameters.Stop};
var result = new Dictionary<string, string>();
result.Add(queryParameters.Name, startStop);
return result;
}
public class StartStop
{
public int Start { get; set; }
public int Stop { get; set; }
}
This may be the perfect case to utilize ExpandoObjects. An ExpandoObject is a dynamic type, whose properties can be created at run time. ExpandoObject implements IDictionary < string, object > so it's easy to convert to a Dictionary < string, object > .
In the example below, an ExpandoObject is created and converted to a Dictionary < string, object > and then converted to a Dictionary < string, string >.
dynamic apiVar = new ExpandoObject();
apiVar.Name = "Test";
apiVar.Start = 1;
apiVar.Stop = 2;
var iDict = (IDictionary<string, object>) apiVar;
/* if you can utilize a Dictionary<string, object> */
var objectDict = iDict.ToDictionary(i => i.Key, i => i.Value);
/* if you need a Dictionary<string, string> */
var stringDict = iDict.ToDictionary( i=>i.Key, i=> i.Value.ToString());
There are also different ways of setting properties on an ExpandoObject. Below is an example of setting a property by a variable name.
dynamic apiVar = new ExpandoObject();
var propertyName = "Name";
apiVar[propertyName] = "Test";
propertyName = "Start";
apiVar[propertyName] = 1;
propertyName = "Stop";
apiVar[propertyName] = 2;
I always reuse the RouteValueDictionary class for this. It has a constructor that accepts any object and the class itself implements IDictionary.
It's available in the System.Web dll
private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject)
{
return new RouteValueDictionary(queryParametersObject).ToDictionary(d => d.Key, d => Convert.ToString(d.Value));
}

Cannot update a single item (object) in a List C#

I have a list of objects:
List<NPortfolio> Portfolios = new List<NPortfolio>();
Portfolios.Add(new NPortfolio(1, "1", emptyPositions));
Portfolios.Add(new NPortfolio(2, "2", emptyPositions));
Now i want to call a Method on the object that modifies its properties:
Portfolios[0].UpdatePositions(db.GetPortfolio(1, Today));
The method is this:
public void UpdatePositions(Dictionary<string, double> valuepairs)
{
foreach (var k in this.positions.Keys.ToList())
{
if (valuepairs.ContainsKey(k))
this.positions[k] = valuepairs[k];
}
}
This works, but the problem is that when I try to update just the first item of the list:
Portfolios[0].UpdatePositions(db.GetPortfolio(1, Today));
ALL ITEMS OF THE LIST ARE UPDATED!!!
I cannot find why all items are updated and not only item 0.
Please help this is really an headache
many thanks
class definition:
public class NPortfolio
{
public string p_id { get; set; }
public int p_nr { get; set; }
private Dictionary<string, double> positions;
public NPortfolio(int nr, string id, Dictionary<string, double> pos)
{
p_nr = nr;
p_id = id;
positions = pos;
}
public void UpdatePositions(Dictionary<string, double> valuepairs)
{
foreach (var k in this.positions.Keys.ToList())
{
if (valuepairs.ContainsKey(k))
this.positions[k] = valuepairs[k];
}
}
public Dictionary<string, double> getPositions()
{
return positions;
}
}
The problem is from this
Portfolios.Add(new NPortfolio(1, "1", emptyPositions));
Portfolios.Add(new NPortfolio(2, "2", emptyPositions));
You are passing the same dictionary to both classes, so if you modify one of the classes you modify both instances.
You must create a new dictionary inside the constructor of NPortfolio so each class has a unique copy.
public NPortfolio(int nr, string id, Dictionary<string, double> pos)
{
p_nr = nr;
p_id = id;
positions = new Dictionary<string, double>(pos);
}
This will make a shallow copy of the dictionary and should solve your issue for now.
You're passing the same dictionary into your objects. So when you update it in one you end up seeing the changes in the other. You should create a new dictionary inside your constructor and populate it with the values passed in.
public NPortfolio(int nr, string id, Dictionary<string, double> pos)
{
p_nr = nr;
p_id = id;
positions = new Dictionary<string, double>(pos);
}

.NET Dictionary as a Property

Can someone point me out to some C# code examples or provide some code, where a Dictionary has been used as a property for a Class.
The examples I have seen so far don't cover all the aspects viz how to declare the dictionary as property, add, remove, and retrieve the elements from the dictionary.
Here's a quick example
class Example {
private Dictionary<int,string> _map;
public Dictionary<int,string> Map { get { return _map; } }
public Example() { _map = new Dictionary<int,string>(); }
}
Some use cases
var e = new Example();
e.Map[42] = "The Answer";
sample code:
public class MyClass
{
public MyClass()
{
TheDictionary = new Dictionary<int, string>();
}
// private setter so no-one can change the dictionary itself
// so create it in the constructor
public IDictionary<int, string> TheDictionary { get; private set; }
}
sample usage:
MyClass mc = new MyClass();
mc.TheDictionary.Add(1, "one");
mc.TheDictionary.Add(2, "two");
mc.TheDictionary.Add(3, "three");
Console.WriteLine(mc.TheDictionary[2]);
EDIT
When you use C# version 6 or later, you can also use this:
public class MyClass
{
// you don't need a constructor for this feature
// no (public) setter so no-one can change the dictionary itself
// it is set when creating a new instance of MyClass
public IDictionary<int, string> TheDictionary { get; } = new Dictionary<int, string>();
}
You could also look into indexers. (official MSDN documentation here)
class MyClass
{
private Dictionary<string, string> data = new Dictionary<string, string>();
public MyClass()
{
data.Add("Turing, Alan", "Alan Mathison Turing, OBE, FRS (pronounced /ˈtjʊ(ə)rɪŋ/) (23 June, 1912 – 7 June, 1954) was a British mathematician, logician, cryptanalyst and computer scientist.")
//Courtesy of [Wikipedia][3]. Used without permission
}
public string this [string index]
{
get
{
return data[index];
}
}
}
Then, once you have populated the dictionary internally, you can access it's information by going
MyClass myExample = new MyClass();
string turingBio = myExample["Turing, Alan"];
EDIT
Obviously, this has to be used carefully, because MyClass is NOT a dictionary, and you cannot use any dictionary methods on it unless you implement them for the wrapper class. But indexers are a great tool in certain situations.
In order to ensure the encapsulation is correct and the dictionary cannot be updated outside the class using Add or the form ExampleDictionary[1]= "test", use IReadOnlyDictionary.
public class Example
{
private Dictionary<int, string> exampleDictionary;
public Example()
{
exampleDictionary = new Dictionary<int, string>();
}
public IReadOnlyDictionary<int, string> ExampleDictionary
{
get { return (IReadOnlyDictionary<int, string>)exampleDictionary; }
}
}
The following code will not work, which is not the case if IDictionary is used:
var example = new Example();
example.ExampleDictionary[1] = test;
Another example of using a dictionary as a static property with only the get accessor:
private static Dictionary <string, string> dict = new Dictionary <string,string>(){
{"Design Matrix", "Design Case"},
{"N/A", "Other"}
};
public static Dictionary <string, string> Dict
{
get { return dict}
}
This structure can be used to replace values.
An example...
public class Example
{
public Dictionary<Int32, String> DictionaryProperty
{
get; set;
}
public Example()
{
DictionaryProperty = new Dictionary<int, string>();
}
}
public class MainForm
{
public MainForm()
{
Example e = new Example();
e.DictionaryProperty.Add(1, "Hello");
e.DictionaryProperty.Remove(1);
}
}
Since .net 4.6 you can also define a Dictionary like this:
private Dictionary<string,int> Values => new Dictionary<string, int>()
{
{ "Value_1", 1},
{ "Value_2", 2},
{ "Value_3", 3},
};
It's called Expression-bodied members!
You mean like a property bag ?
http://www.codeproject.com/KB/recipes/propertybag.aspx

Categories

Resources