Create a key value pair in c# - c#

I have been trying to create a class which has a property for key value pair, I have tried the Dictionary keyword, but I need something like this:
ClassName clsName = new ClassName();
clsName.PropertyName.Add["Key"] = value;
I want it to be dynamic property so I can send any datatype.

If we suppose that your keyvaluepair has as a key a string and as a value an int, then you could try this one:
clsName.PropertyName = new KeyValuePair<string, int>("keyName", 2);
You don't need to use the any Add method. Actually, the latter makes sence when you have a collection an you want to add to it an item. From that you have posted in your question, we can't say that this is your case.

I suggest you to simply use the "HASHTABLE" its so much easier for you.Below is syntax.
Hashtable hashtable = new Hashtable();
hashtable.Add("Area", 1000);
hashtable.Add("Perimeter", 55);
1st parameter represents the key and 2nd one represents the value.So its the key value pair.

If you are after a basic class, for key and value, would
KeyValuePair<string, object>
work for you?

I'm not sure if I understood the question correctly, but apparently your requirements can be met using a generic Dictionary, where the key type parameter is string and the value type parameter is object, i.e. you could use Dictionary<string,object> like this:
public class ClassName {
public Dictionary<string, object> Dictionary { get; set; }
}
And then:
ClassName classObject = new ClassName();
classObject.Dictionary.Add("Key", new { "value" });

public class ClassName
{
public KeyValuePair<string, object> PropertyName {get; set; }
}
var c = new ClassName();
c.PropertyName = new KeyValuePair<string, object>("keyName", someValue);
or, if you need to store multiple values, use Dictionary<string, object> as type of your property.
public class ClassName
{
public ClassName()
{
this.PropertyName = new Dictionary<string, object>();
}
public Dictionary<string, object> PropertyName {get; set; }
}
var c = new ClassName();
c.PropertyName.Add("stringKey", anyValue);

Related

Use list of inherited classes as parameter and return a dictionary of them

I want to have a method that converts a list of a given type to a dictionary of that type, but I want the type to be a class inherited from my XMLData class, so that I can use the Name attribute as the key for the dictionary.
Here's the code:
public static class SomeTools
{
public static Dictionary<string, XMLData> ConvertToDictionary(List<XMLData> xmlDataList)
{
Dictionary<string, XMLData> dict = new Dictionary<string, XMLData>();
foreach(XMLData data in xmlDataList)
{
dict.Add(data.Name, data);
}
return dict;
}
}
This works fine with getting just a dictionary of XMLData, but I can't use it to get a dictionary of LocationData. Here's the code that gets executed to try to retrieve location data.
List<LocationData> datalist = new List<LocationData>();
Dictionary<string, LocationData> locationData = SomeTools.ConvertToDictionary(datalist);
Well after a bit of trial and error with different approaches, I found one that worked.
This is my new code:
public static Dictionary<string, XMLData> ConvertToDictionary<XMLData>(List<XMLData> xmlDataList)
{
Dictionary<string, XMLData> dict = new Dictionary<string, XMLData>();
foreach(XMLData data in xmlDataList)
{
dynamic d = data;
dict.Add(d.Name, data);
}
return dict;
}
I don't know how I feel about the dynamic being in there, but it got things to work.

C# make a Dictionary of Lambdas

I'm having a trouble defining a Dictionary for quick accessing Lambda Expressions.
Let's suppose we have a well-known class like this:
class Example
{
public string Thing1;
public DateTime Thing2;
public int Thing3;
}
What a want to do is something like this:
var getters = new Dictionary<string, IDontKnowWhatGoesHere>();
getters.Add("Thing1", x => x.Thing1);
getters.Add("Thing3", x => x.Thing3);
Is this possible?
Edit:
This is my use case for this object:
List<Example> array = new List<Example>();
// We actually get this variable set by the user
string sortField = "Thing2";
array.Sort(getters[sortField]);
Many thanks for your help.
You've got a couple of options. If, as in your example, the things you want to get are all the same type (i.e. String), you can do
var getters = new Dictionary<string, Func<Example, String>>();
However, if they're different types, you'll need to use the lowest common subclass, which in most cases will be Object:
var getters = new Dictionary<string, Func<Example, object>>();
Note that you'll then need to cast the return value into your expected type.
Try:
var getters = new Dictionary<string, Func<Example, object>>();
getters.Add("Thing1", x => x.Thing1);
getters.Add("Thing3", x => x.Thing3);
The first generic type parameter of the Func delegate is the type of the input, and the second generic type parameter is the type of the output (use object because you've different output types).
More about Func: Func<T, TResult> Delegate
var getters = new Dictionary<string, Expression<Func<Example, object>>>();
However, string Thing1 should be public.
I really think you are thinking about this in the wrong way. Why use a dictionary at all? If your class definition is correct, then just use a List<Example>.
List<Example> dataList = new List<Example>();
dataList.Add(new Example { Thing1 = "asdf", Thing2 = "qwert", Thing3 = 2 });
Then you can use linq on it.
IEnumerable<Example> sortedByT3 = dataList.OrderBy(x => x.Thing3);
sortedByT3.Last().Thing2 = "hjkl";
You can also use a dynamic order by provided by Marc Gravell's answer:
var sortedByString = dataList.AsQueryable().OrderBy("Thing2");
No need for lambdas, just direct access to the data.
As everyone has said, you need to make the members public. I would suggest you change it to the following:
public class Example
{
public string Thing1 { get; set; }
public string Thing2 { get; set; }
public int Thing3 { get; set; }
}

How to create tree like structure

I want to create the data structure like below.
For this one I want go for keyvaluepair structure. But I am unable to create it.
public class NewStructure
{
public Dictionary<string, Dictionary<string, bool>> exportDict;
}
Is it a right way. If so how I can insert values to it. If I insert like
NewStructure ns = new NewStructure();
ns.exportDict.Add("mainvar",Dictionary<"subvar",true>);
it is giving compile error.
Nothing comes to my mind. Any suggestions please.
You can get rid of error by
Dictionary<string, bool> values = new Dictionary<string, bool> ();
values.Add("subvar", true);
ns.exportDict.Add("mainvar", values);
But probably you`d better try something like this:
class MyLeaf
{
public string LeafName {get; set;}
public bool LeafValue {get; set;}
}
class MyTree
{
public string TreeName {get; set;}
public List<MyLeaf> Leafs = new List<MyLeaf>();
}
And then
MyTree myTree = new MyTree();
myTree.TreeName = "mainvar";
myTree.Leafs.Add(new MyLeaf() {LeafName = "subvar", LeafValue = true});
For one, you'll have to initialize each of the dictionaries before you add to them:
exportDict = new Dictionary<string, Dictionary<string, bool>>();
Dictionary<string,bool> interiorDict = new Dictionary<string,bool>();
interiorDict.Add("subvar", true);
exportDict.Add("mainvar", interiorDict);
But if you know your interior dictionary is only going to have one key value pair then you can do:
exportDict = new Dictionary<string, KeyValuePair<string,bool>>();
exportDict.Add("mainvar", new KeyValuePair<string,bool>("subvar", true));
If you are on C# 4.0, you can accomplish this with a Dictionary<> of KeyValuePair<>
Your NewStructure would become
public class NewStructure
{
public Dictionary<string, KeyValuePair<string, bool>> exportDict =
new Dictionary<string, KeyValuePair<string, bool>>(); //this is still a dictionary!
}
and you'd use it like this:
NewStructure ns = new NewStructure();
ns.exportDict.Add("mainvar",new KeyValuePair<string,bool>("subvar",true));
With a dictionary of dictionaries you would make each "leaf" a list in itself.

Any existing Dictionary<T, List<T>> in which the value collection cannot contain the key

I need the following (using string as the type here for brevity):
MyDictionary : IDictionary<string, List<string>>
{
private readonly Dictionary<string, List<string>> _collection;
...
// The collection cannot contain the key
public void Add(string key, List<string> value)
{
_collection.Add(key, new List<string>(value.RemoveAll(p => p == key));
}
}
So in use you might have:
string myName = "Superstringcheese";
List<string> myFriends = new List<string> {"John", "Jane", "Jerry"};
string yourName = "Someone";
List<string> yourFriends = new List<string> {"John", "Bill", "Ted"};
var myDic = new MyDictionary();
// It's okay that each of us (each key) has some friends that are the same. It's not okay for me to have myself as a friend. The add method would check if the key is contained by the value collection and remove it if necessary.
myDic.Add(myName, myFriends);
myDic.Add(yourName, yourFriends);
Before I go reinventing any wheels, is there a native collection type that does this, or does anyone know of a popular implementation?
Well, I can help with this bit:
Is there a native collection type that does this?
No.

How to initialize auto-property to not null in C#?

I have a property:
public Dictionary<string, string> MyProp { get; set; }
When I invoke that property to add an item, I get a NullReferenceException.
How would I do the null check in the property itself so it gives me a new one if it is null? While keeping in the auto-property pattern.
Without an explicit private variable the only other way would be to add some code to the constructor of the class:
MyProp = new Dictionary<string,string>();
You can initialize it in your constructor:
public MyClass()
{
MyProp = new Dictionary<string, string>();
}
I don't think you will want a setter, since that will always make a new dictionary, as others have pointed out by calling the setter in the constructor. A better approach is:
public Dictionary<string, string> MyProp { get; internal set; }
public MyClass() { MyProp = new Dictionary<string, string>(); }
Here you've used the internal setter to create the dictionary. After this, if you want to add an element to the dictionary, you would do this in your code:
InstanceOfMyClass.MyProp.Add(blah, blah);
where you use the getter to get the dictionary object, then do an Add to add a new item. You can't call the setter from your code and accidentally wipe out the dictionary, because it will look readonly to anything outside of MyClass.
For other people falling over this old question, there is a new feature in C# 6.0.
In C# 6.0, you can also initialize that property to some constant value in the same statement, like this:
public Dictionary<string, string> MyProp { get; set; } = new Dictionary<string, string>();
Initialize it in the constructor
public MyClass(){ dictionary = new
Dictionary<string,string>()
}
You will have to use an explicit backing field, you cannot change the getter or setter for auto-properties.
There's an attribute class named DefaultValueAttribute that allows you to specify the desired default value of a member, however, it doesn't automatically set the member to the value specified; hope is not lost, though, as you can use reflection to retrieve this value at runtime and apply it, as posed in this corner of the internet:
static public void ApplyDefaultValues(object self)
{
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(self))
{
DefaultValueAttribute attr = prop.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
if (attr == null) continue;
prop.SetValue(self, attr.Value);
}
}
I haven't tested this, and there may be issues with certain types but I'll leave it to your consideration and discretion. Should you decide to implement this then improvements could certainly be made.
If you were to run this code, you would get a NullReferenceException because the field is never initialized.
class Program
{
static void Main(string[] args)
{
Person sergio = new Person();
sergio.Items.Add("test", "test");
Console.ReadKey();
}
public class Person
{
public Dictionary<string, string> Items { get; set; }
}
}
So one way to solve this would be to initialize it, in the class´s constructor.
class Program
{
static void Main(string[] args)
{
Person sergio = new Person();
sergio.Items.Add("test", "test");
Console.ReadKey();
}
public class Person
{
public Dictionary<string, string> Items { get; set; }
public Person()
{
Items = new Dictionary<string, string>();
}
}
}

Categories

Resources