I have a class that is instantiated at the beginning of each iteration of a loop. Inside the loop, it's attributes need to be populated with the row values of a table returned by a stored procedure. As I have to iterate through each column of every row, in order to know which attribute of the class needs to be assigned a value and when, I have a dictionary that maps the column names to an index. This index refers to a position in a list that stores an attribute of an instance of the class:
while (reader.Read() && reader.HasRows)
{
Subscription subscription = new Subscription();
List<string> subscrData = new List<string>
{
subscription.attr1,
subscription.attr2,
subscription.attr3,
subscription.attr4
}
Dictionary<string, int> columnDict = new Dictionary<string, int>
{
{"attr1": 0},
{"attr2":1},
{"attr3":2},
{"attr4":3}
}
foreach (string colName in columnDict.Keys)
{
if (reader.GetSchemaTable().Columns[colName] == null)
subscrData[columnDict[colName]] = "null";
else
{
subscrData[columnDict[colName]] = reader[colName].ToString();
nullsReturned = false;
}
}
I'm probably coming at this from more of a C++ approach as with that you could store references to the class instance an modify its attributes, but this doesn't work with C# because lists store the values.
How can I restructure this code so that I can modify the actual attributes of the class instance while still being able to check if each column returned from the stored procedure is not null?
You don't need the list for this case. You either want to add a method like setAttribute(string attributeName) to your class (and within it build a switch/case to modify the given attribute); or, use reflection to change an instance field given its name.
I agree with Hasan. But just for your information: to implement your approach you could make use of Lambda expressions to keep track of the references to your properties (= the attributes).
Something like this would work:
Subscription subscription = new Subscription();
List<Expression<Func<Subscription, string>>> subscrData = new List<Expression<Func<Subscription, string>>>
{
a => a.attr1,
a => a.attr2,
a => a.attr3,
a => a.attr4,
};
//E.g. To update attribute 3 you can do this:
var prop = (PropertyInfo)((MemberExpression)subscrData[2].Body).Member;
prop.SetValue(subscription, "test string", null);
I want to get value from dictionary but i don't know key(Because dynamic generate dictionary from database) how can i get dictionary value.
If you some idea share me ...
For Example my database string value like
string jsonString = " "FB": "[{\"title\":\"sheet1\",\"rows\":[{\"height\":\"undefined\",\"columns\":[{\"value\":\"Cover Group \"},{\"value\":\"Sample Variable\"},{\"value\":\"Coverpoint Name\"},{\"value\":\"Crossed cover points\"},{\"value\":\"Coverpoint Comment\"},{\"value\":\"Bin Type\"},{\"value\":\"Bin Id\"},{\"value\":\"Sample Value\"},{\"value\":\"Expected Bin Count\"},{\"value\":\"Set Max Bin\"},{\"value\":\"Not Used\"}]},{\"height\":\"undefined\",\"columns\":[{\"value\":\"allCg,allSi\"},{\"value\":\"exSingle\"},{\"value\":\"exSingle\"},{},{\"value\":\"Example for single bin\"},{\"value\":\"single\"},{\"value\":\"valZero\"},{\"value\":\"1'b0\"},{\"formula\":\"1\",\"value\":1},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{\"value\":\"single\"},{\"value\":\"valOne\"},{\"value\":\"1'b1\"},{\"formula\":\"1\",\"value\":1},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex1Bus[3:0]\"},{\"value\":\"exMulti\"},{},{\"value\":\"Example for multibin\"},{\"value\":\"multi\"},{},{\"value\":\"[0:15]\"},{\"formula\":\"16\",\"value\":16},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{\"value\":\"exCross\"},{\"value\":\"exSingle,exMulti\"},{\"value\":\"Example for cross\"},{\"value\":\"Implicit\"},{},{},{\"formula\":\"32\",\"value\":32},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex2Bus[15:0]\"},{\"value\":\"exWildcard\"},{},{\"value\":\"example for wildcard\"},{\"value\":\"wildcard\"},{\"value\":\"ex_wildcard\"},{\"value\":\"16'bxxxxxxxxxxxxxx1\"},{\"formula\":\"1\",\"value\":1},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex3Bus[4:0]\"},{\"value\":\"exImplicit\"},{},{\"value\":\"example for implicit & set max bin\"},{\"value\":\"Implicit\"},{},{},{\"formula\":\"8\",\"value\":8},{\"formula\":\"8\",\"value\":8},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex4Bus[3:0]\"},{\"value\":\"ex4Bus\"},{},{\"value\":\"setup for ignore example\"},{\"value\":\"multi\"},{},{\"value\":\"[0:15]\"},{\"formula\":\"16\",\"value\":16},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{\"value\":\"exIgnore\"},{\"value\":\"exSingle,ex4Bus\"},{\"value\":\"example for ignore\"},{\"value\":\"ignore\"},{},{\"value\":\"ex4Bus([12:15])\"},{\"formula\":\"24\",\"value\":24},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{\"value\":\"ex5Bus[3:0]\"},{\"value\":\"exIllegal\"},{},{\"value\":\"example for illegal\"},{\"value\":\"illegal\"},{},{\"value\":\"[12:15]\"},{\"formula\":\"16\",\"value\":16},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]},{\"height\":\"undefined\",\"columns\":[{},{},{},{},{},{},{},{},{},{},{}]}],\"metadata\":{\"widths\":[\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\",\"200\"],\"frozenAt\":{\"row\":0,\"col\":0}}}]""
FB is dynamic key and after it's value title all value i need
If you don't have the key, but have the value and trying to get hold of the key, you can do this:
Dictionary<string, string> testData = new Dictionary<string, string>();
testData.Add("name", "Latheesan");
testData.Add("age", "26");
KeyValuePair<string, string> searchResult
= testData.FirstOrDefault(s => s.Value == "Latheesan");
string key = searchResult.Key; // returns "name" here
To get a sequence of all the Key/Value pairs where the value matches a target:
var dict = new Dictionary<string, int>
{
{"One", 1},
{"Two", 2},
{"Another One", 1},
{"Three", 3},
{"Yet Another One", 1}
};
int target = 1; // For example.
var matches = dict.Where(item => item.Value == target);
foreach (var kvp in matches)
Console.WriteLine("Key = " + kvp.Key);
The sample data you posted isn't a flat key-value dictionary. It contains embedded dictionaries - the base dictionary contains a title and a rows, which in turn consists of height and columns and so on, and at some point are key-value pairs who keys are, confusingly, named 'value'. Are you asking how to parse this data structure to get all the values whose key is value?
What you first need to do, since this appears to be a JSON-formatted entry, is parse the JSON into a .NET data structure, using libraries like JSON.NET or System.Web.Helpers.Json. These libraries will convert the JSON string into a hierarchy of dictionaries, all of them implementing IEnumerable, so you can iterate over it, more or less like this (this is not compilable code, just a demonstration!):
public void Main()
{
var jsonObject = Json.Decode(FB); // FB is your JSON string.
var values = new List<string>();
FindValues(jsonObject);
}
public void FindValues(jsonObject, values)
{
foreach (var child in jsonObject)
{
if (child.key == 'value')
{
values.Add(child.value);
}
// Recursively call FindValues on child objects.
FindValues(child, values);
}
}
This C#-ish pseudo-code shows you how to go over a dictionary, then optionally drill down deeper into internal dictionaries.
This code use for get value from dictionary value without knowing key and value..
var json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonString );
var javSer = new JavaScriptSerializer();
var dfi = javSer.Deserialize<Dictionary<string, string>>(json);
string dataString= dfi.Values.First();
How can you possibly know which value you need if you don't have the key?
A Dictionary in .NET does contain a Keys and Values collection, so if you are only interested in the values, you can use that.
How do I make a generated Object name? For example:
ObjectEx "name" = new ObjectEx();
Edit:
The object will be named by a user input.
The code will be:
Console.Write("Input new user's name: ");
string newUsersName = Console.ReadLine();
(Create ObjectEx)
Edit2:
I have a Dictionary for ObjectEx(Person) which handles all ObjectExs.
Person is the real class name, sorry about making the example object ObjectEx.
public static List<Person> persons = new List<Person>();
Objects don't have names - variables do, and they're always determined at compile-time.
If you want a map from string to object, just use a Dictionary<string, ObjectEx> - then come with random strings using Random. (There are plenty of examples of generating random strings on Stack Overflow.)
If you just want a collection of objects and you were using "random name" as a way of expressing that, use List<ObjectEx> - you don't need a name at all in that case.
If you need something else, please be more specific.
You can use array and store object in to that.
ObjectEx []arrObjectEx = new ObjectEx[10];
arrObjectEx[0] = new ObjectEx();
I would use list<T> (generic list) instead of array if the number of random elements are unknown.
List<ObjectEx> lstObjectEx = new List<ObjectEx>();
lstObjectEx.Add(new ObjectEx());
If randomly generated object need to be accessed uniquely then you can use dictionary. e.g
Dictionary<int, ObjectEx> dicObjectEx = new Dictionary<int, ObjectEx>();
dicObjectEx.Add(someUniqueNumber, new ObjectEx());
That is not possible but how about using a Dictionary. You can use a string value Add and Get hold of an Object you stored.
// somewhere near the start in your code initialize the dictionary
var dict = new Dictionary<string, Person>();
// later on you can dynamically add an Object to the Dictionary
// newUsersName is the so called Index
string newUsersName = Console.ReadLine();
dict.Add(newUsersName, new Person());
// if you need to get hold of that object again use the Index
// myObj is a Person type
var myObj = dict[newUsersName];
// assume Person has an Age property
myObj.Age = 20;
// show all Persons now in the dictionary
foreach(var username in dict.Keys)
{
Console.WriteLine(username);
var pers = dict[username];
Console.WriteLine("{0} is {1} years old", username, pers.Age );
}
You could use a dictionary to store objects, where the Key is the object name
I would like to know how to get the name of the property that a method parameter value came from. The code snippet below shows what I want to do:
Person peep = new Person();
Dictionary<object, string> mapping = new Dictionary<object, string>();
mapping[peep.FirstName] = "Name";
Dictionary<string, string> propertyToStringMapping = Convert(mapping);
if (mapping[peep.FirstName] == propertyToStringMapping["FirstName"])
Console.WriteLine("This is my desired result");
private Dictionary<string, string> Convert(Dictionary<object, string> mapping)
{
Dictionary<string, string> stringMapping = new Dictionary<string, string>();
foreach (KeyValuePair<object, string> kvp in mapping)
{
//propertyName should eqal "FirstName"
string propertyName = kvp.Key??????
stringMapping[propertyName] = kvp.Value;
}
return stringMapping;
}
You are not able to do so in this way, since the way it works is that C# evaluates the value of FirstName property by calling its get accessor and passes the value of that to the indexer of the dictionary. Therefore, the way you found out FirstName value is completely lost. Just like the way you evaluate 2 + 2.
If you write, "x = 2 + 2", x will have the value 4 but there will be no way to tell if it was 3 + 1 or 2 + 2 or 5 + (-1) or ... that evaluated to 4.
I think ultimately you will need to store either the PropertyInfo object associated with the property, or the string representation of the property name in you mapping object. The syntax you have:
mapping[peep.FirstName] = "Name";
Would create an entry in the dictionary with a key value equal to the value of the peep.FirstName property, and the Value equal to "Name".
If you store the property name as a string like:
mapping["FirstName"] = "Name";
You could then use reflection to get the "FirstName" property of your object. You would have to pass the "peep" object into the Convert function, however. This seems to be somewhat opposite of what you are wanting to do.
You may also be able to get crazy with Expressions and do something like:
var mapping = new Dictionary<Expression<Action<T>>,string>();
mapping[ p => p.FirstName ] = "Name";
Then in your Convert function you could examine the expression. It would look something like:
private Dictionary<string,string> Convert(Dictionary<Expression<Action<T>>,string> mapping)
{
var result = new Dictionary<string,string>();
foreach(var item in mapping)
{
LambdaExpression ex = item.Key as LambdaExpression;
string propertyName = ((MemberExpression)ex.Body).Member.Name;
string propertyValue = item.Value;
result.Add(propertyName,proeprtyValue);
}
return result;
}
This is more or less off the top of my head, so I may have the expression types off a bit. If there are issues with this implementation let me know and I will see if I can work out a functional example.
I don't know much about C#, but I suppose peep is an enum? As for Java, you could do:
String propertyName = kvp.key.toString()
Maybe there's something similar in C#?
And even if peep isn't a enum: I see no reason why the key should be an arbitrary object? So maybe the solution is exactly to use an enum as type of the key?
Also, I don't know what you're trying to do but usually, I'd not recommend you to convert the enum key to a string. What can you do with a string what you can't do, too, with an enum?