Using variable in the name - c#

Is it possible to use a variable to access 2 variables without naming another variable?
For example, to:
LOG.dig.CNLog = 7;
LOG.value.CNLog = 17;
I would like to use something like this
string a = "dig";
string b = "value";
LOG.[a].CNLog = 7;
LOG.[b].CNLog = 17;
It's possible to use this? If yes what is the correct format?
Thanks

You can use a Dictionary<string, int>. An example:
var dict = new Dictionary<string, int>();
dict.Add("test", 1);
var testVal = dict["test"];

You can do that by using a Dictionary<TKey, TValue>.
A dictionary is a collection of keys and values. In your case you probably would like to use a Dictionary<string, LogClass> then you can have something like this:
Assuming LogClass is your class...
public class LogClass
{
public int CNLog { get; set; }
}
string a = "dig";
string b = "value";
dictionary[a].CNLog = 7;
dictionary[b].CNLog = 17;
But of course before doing that you would have to say what is the value that goes into dictionary[var].
dictionary[a] = new LogClass();
That is how you would use it, hopefully you will be able to adapt this solution to your code.
And you can check out a video that explains step-by-step very slowly and clearly how to work with it on Microsoft Virtual Academy: C# Fundamentas at 22:00.

Related

Create variable which will be named with listValue

I'm having a little problem with creating variable which will be named by list value.
Here is an example with what I want.
for (int i = 0; i < list.Count; i++)
{
//here I want to create variable
//which will be named with list[i]
}
So if list has 2 elements eg.
list[0] = "testName"
list[1] = "andAnotherOne"
I want to create 2 variables,
one of them is named testName and the second one andAnotherOne
Can you help me complete it?
I believe you need a Dictionary as said by TaW. This allows you to have the value same as the index.
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("foo","foo"); //index,value of index
if(dictionary.ContainsKey["foo"])
{
string value = dictionary["foo"];
Console.Write(value);
}
I hope I understood your question.
Just create A List<string> names = new List<string>();
for (int i = 0; i < 5; i++)
{
names.Add("sample" + i);
}
EDIT:
If you want to refer with names then use a dictionary like below,
Dictionary<string, string> myvalues = new Dictionary<string, string>();
You can use dynamic and ExpandoObject:
var variables = new List<string> { "variableOne", "variableTwo" };
dynamic scope = new ExpandoObject();
var dictionary = (IDictionary<string, object>)scope;
foreach (var variable in variables)
dictionary.Add(variable, "initial variable value");
Console.WriteLine(scope.variableOne);
Console.WriteLine(scope.variableTwo);
In C#, variables are all statically declared. I think you can't do that. Maybe you can try with the reflection but I think it won't able you to do what you want.
Some things I found that could interest you :
string to variable name
Convert string to variable name

print all variables in class C#

To start I would prefer not to use reflection to accomplish this.
I have a class lets say
public class exampleClass
{
public string var1 = "one";
public string var2 = "two";
public int var3 = 3;
public string var4 = "four";
etc. etc..
}
I want to dynamically be able to iterate through that class and print out the variables. I thought about serialization but wasn't exactly sure how to implement it for this case (the only examples I could find were to XML and I don't want that) also I don't really want to change the structure of the class in any way.
The reason I'm doing that is because I'm constructing an HTML table and want to do:
for(int i = 0; i < exampleClass.Count; i++)
tbl_row = "<td>" + exampleClass[i] + "</td>";
or something similar. Any suggestions?
The easisets way would be using reflection. This should be enough :
var example = new exampleClass();
var allPublicFields = example.GetType().
GetFields(BindingFlags.Public | BindingFlags.Instance );
Use a dictionary, instead of fields: Dictionary<fieldName, fieldValue> , but this is
kind over engineering the simple a streghtforward solution: reflection over clear and maintanable structure of your strong typed class.
Complete same for building HTML with TagBuilder.
var tagBuilder = new TagBuilder("tr");
var exampleClass = new exampleClass();
tagBuilder.InnerText += "<td>Field</td><td>Value</td>";
foreach(var field in typeof(exampleClass)
.GetFields(BindingFlags.Public | BindingFlags.Instance))
{
var nameBuilder = new TagBuilder("td");
var valueBuilder = new TagBuilder("td");
nameBuilder.InnerHtml = field.Name;
valueBuilder.InnerHtml = field.GetValue(exampleClass).ToString();
tagBuilder.InnerHtml += string.Format("{0}{1}",
nameBuilder.ToString(),
valueBuilder.ToString());
}
outputs:
<tr>
<td>Field</td><td>Value</td>
<td>var1</td><td>one</td>
<td>var2</td><td>two</td>
<td>var3</td><td>3</td>
<td>var4</td><td>four</td>
<tr>
If you don't want to use reflection, how about storing the data in a dictionary, rather than in a custom class? That way you can simply iterate over the keys or values as required.
Personally, I think you're better off with reflection. You could achieve what you're trying to do if you're using .NET 4 or later and derive exampleClass from DynamicObject.
The example on this page is pretty similar to what you're looking to do.

C# Putting a class in a dictionary and creating a new instance on call

This really seems confusing but I want to create a Dictionary filled with different classes as the Values, then using letters as the keys. When I call a key in that dictionary, I need it to act as though I'm typing "new ClassInDictionary".
This is so I can create a text file with different symbols defining different blocks.
To help clear things up here's my current code:
blockIdentifier.Add("=", new BlockAir()); // Define which class corresponds to which letter
blockIdentifier.Add("-", new BlockDirt());
for (int mapX = 0; mapX < mapWidth; mapX++)
{
for (int mapY = 0; mapY < mapHeight; mapY++)
{
try
{
Block block = blockIdentifier[mapSplit[mapY].Substring(mapX, 1)]; // Simply find which letter to use, let's pretend it's: "="
// The line above should be creating a new instance of the class BlockAir
block.blockX = mapX * 45;
block.blockY = mapY * 45;
mapList[mapY, mapX] = block;
}
catch (Exception)
{
}
}
}
The variable blockIdentifier:
public static Dictionary<string, Block> blockIdentifier = new Dictionary<string, Block>();
And BlockDirt:
public class BlockDirt : Block
{
public int hi;
public BlockDirt()
: base("Dirt Block.png", 0, 0, true)
{
}
}
I simply need to call blockIdentifier["="] and get a new instance of the class BlockDirt(), how can I do this?
Do you want to create a new instance of the block each time or re-use a single instance of the block?
From the code it looks as if you want to create a new one each time. If so, one way is to make it a Dictionary<string, Func<Block>> where all the blocks inherit from Block (or IBlock, which might be a bit better).
note
Assumes BlockAir : IBlock and BlockDirt : IBlock
var blockLookup = new Dictionary<string, Func<IBlock>>();
blockLookup.Add("=", ()=> new BlockAir());
blockLookup.Add("-", ()=> new BlockDirt());
...
mapList[x,y] = blockLookup[symbol]();
...
or along those lines (I haven't got access to a dev. environment at the moment so apologies for any errors)
You could do this by storing ConstructorInfo objects in your dictionary and then create objects via reflection. Maybe kind of hacky, but I think it will work.
Here is an example using StringBuilder constructor in a dictionary (you can throw this in LINQPad to see the output).
var creator = typeof(StringBuilder).GetConstructor(new Type[]{});
var dict = new Dictionary<string, ConstructorInfo>();
dict["a"] = creator;
StringBuilder b = (StringBuilder)dict["a"].Invoke(new object[]{});
b.AppendLine("Hello World");
b.ToString().Dump();
So for your case, you want constructors for your different Block objects:
var blockIdentifier = new Dictionary<string, ConstructorInfo>();
blockIdentifier["="] = typeof(BlockAir).GetConstructor(new Type[]{});
blockIdentifier["-"] = typeof(BlockDirt).GetConstructor(new Type[]{});
I'd say the most logical way to do it would be to have Type values in the dictionary
var blockIdentifier = new Dictionary<string, Type>();
blockIdentifier.Add("=", typeof(BlockDirt));
blockIdentifier.Add("-", typeof(BlockAir));
....
mapList[x,y] = blockIdentifier[symbol].GetConstructor(new Type[] { }).Invoke(null);

How to have n variables in C#

imagine this code
for (int iDay = 1; iDay <= total_days; iDay++)
{
question = CheckString(s.challenge_1_q);
answer = CheckStringA(s.challenge_1_a);
// more here
}
but what I really have is from challenge_1_q to challenge_24_q and challenge_1_a to challenge_24_a
what is my best option to have dynamic variables as today it's 24, "tomorrow" could be only 18.
is the use of dynamic the proper way? or I really need to have a switch and forget about dynamism ?
Create a class called QuestionAnswer, then store a List on s.
The accessing code will look like this:
question = CheckString(s.QuestionAnswers[i].Question);
answer = CheckStringA(s.QuestionAnswers[i].Answer);
The QuestionAnswer class:
public class QuestionAnswer
{
public string Question{get; set;}
public string Answer{get; set;}
}
And the definition on your existing class:
public List<QuestionAnswer> QuestionAnswers = new List<QuestionAnswer>();
Instead of having dozens of variables, you add dozens of items to the list:
QuestionAnswer qa = new QuestionAnswer();
qa.Question = "What letter comes after A?";
qa.Answer = "B";
QuestionAnswers.Add(qa);
//repeat for all your questions.
You can also create Structure
struct QuestionBank
{
public string Question;
public string Answer;
}
And use Something like this
QuestionBank []Quiz = new QuestionBank[n]; //n is number of question and answers
Quiz[0].Question = "SomeQuestion";
Quiz[0].Answer = "SomeAnswer";
Quiz[1].Question = "SomeAnotherQuestion";
Quiz[1].Answer = "AnswerAsWell";
.....
Quiz[n].Question = "nth Question";
Quiz[n].Answer = "nth AnswerAsWell";

C# Array Conversion

Any help here as I'm a C# noob. The following code works fine and returns 1 string ViewState2. I'd like it to return an array of ViewState2 and EventValidation2 so I can manipulate it later on. How would I convert the code below to return an array?
public string get_status(string local_fname)
{
var dts_doc = new HtmlAgilityPack.HtmlDocument();
dts_doc.Load(local_fname);
//Pull the values
var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
string ViewState2 = ViewState.Attributes[3].Value;
string EventValidation2 = EventValidation.Attributes[3].Value;
//Display the values
//System.Console.WriteLine(ViewState.Attributes[3].Value);
//System.Console.WriteLine(EventValidation.Attributes[3].Value);
//System.Console.ReadKey();
return ViewState2;
}
Don't use an array, but a class. Doing this, you don't have to remember what each element means.
public class Status
{
public string ViewState {get; set;}
public string EventValidation {get; set;}
}
using System;
using HtmlAgilityPack;
[...]
public Status GetStatus(string localFileName)
{
var dtsDoc = new HtmlDocument();
dtsDoc.Load(localFileName);
//Pull the values
var viewStateNode = dtsDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var eventValidationNode = dtsDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
string viewState = viewStateNode.Attributes[3].Value;
string eventValidation = eventValidationNode.Attributes[3].Value;
//Display the values
//Console.WriteLine(viewState);
//Console.WriteLine(eventValidation);
//Console.ReadKey();
return new Status
{
ViewState = viewState,
EventValidation = eventValidation
}
}
Also, you should read up on coding guidelines and naming conventions in the C# language, also the using statement might be interesting. I have corrected some "mistakes", but probably didn't catch all. Also, I have renamed a couple of variables, to make their content clearer. You also might want to look into using the var keyword only in a loop, while using LINQ (or anomynous types in general) or with really long class names. Written out type names can increase readability quite a lot.
If you really want an array with ViewState2 and EventValidation2 in it, you can make the following changes:
// Notice: return value of string[] instead of string
public string[] get_status(string local_frame);
And:
// Notice: returning an array
return new string[] { ViewState2, EventValidation2 };
That said, this is really the "quick and dirty" approach, and is not really appropriate if you're going to want this code to be maintainable (when's the last time you read documentation on a function that "returns an array of length 2, with a string representing X as the first element and another string representing Y as the second"?).
Femaref's right; the correct thing to do would be to encapsulate the information you want returned in its own type.
Assuming you answer yes to this question (although I'd recommend a different approach, see below) this will do what you're asking:
public String[] get_status(string local_fname)
{
var dts_doc = new HtmlAgilityPack.HtmlDocument();
dts_doc.Load(local_fname);
//Pull the values
var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
string ViewState2 = ViewState.Attributes[3].Value;
string EventValidation2 = EventValidation.Attributes[3].Value;
String[] retValues = new String[2];
retValues[0] = ViewState2;
retValues[1] = EventValidation2;
return retValues;
//Display the values
//System.Console.WriteLine(ViewState.Attributes[3].Value);
//System.Console.WriteLine(EventValidation.Attributes[3].Value);
//System.Console.ReadKey();
return ViewState2;
}
That said, I would follow the approach afte the line.
I'd write a class that has the data members you want:
public class DataClass
{
public string ViewState { get; set; }
public string EventValidation { get; set; }
}
Then I'd modify the method to return an instance of your data class.
public DataClass get_status(string local_fname)
{
var dts_doc = new HtmlAgilityPack.HtmlDocument();
dts_doc.Load(local_fname);
//Pull the values
var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
var dc = new DataClass();
dc.ViewState = ViewState.Attributes[3].Value;
dc.EventValidation = EventValidation.Attributes[3].Value;
return dc;
}
string[] array = new string[2];
array[0] = ViewState2;
array[1] = EventValidation2;
return array;
But it seems to trivial as answer. Please Does it solve your problem? If no, can you specify better the question please?

Categories