My environment is: W7 Ultimate 64 bits, VS2010 Ultimate, C#, WinForm, target XP and W7.
With the help of #dasblinkenlight, the concatenation on the for loop was very good.
I feel we are making great progress.
As you ca see, we are putting into the array sMntHour[d,h] the string "csv_001_01" if d=1 and h=1 and so on.
This csv_001_01, csv_001_02,.. ; are variables that contains an integer value.
csv_001_01=5111;
csv_001_02=236; // This is a sample, because has 365 days in normal year
// and 366 days in leaf year. "csv_day_hour"
Directly we could do this:
sMntHour[d,h] = csv_001_01.ToString(); // d is day and h is hour
sMntHour[d,h] = csv_001_02.ToString();
As we put the value of this concatenated variable in the array and not the name of the variables?
for(int d=1;d<=365;d++) //I'll put the code to not leap years.
{
for(int h=1; h<=24; h++)
{
sMntHour[d,h] = string.Format("csv_{0:000}_{1:00}", d, h)
}
}
If I understand what you mean, you have all the variable names and now you want to get their values.
You could do this using Reflection and you can create a dictionary where keys are the variable names and the values are the actual values. It is really hard to help without seeing how these variables are declared, are they fields / properties ? are the private, static ? etc... But something like this should work, in theory:
var type = this.GetType();
var values = sMntHour.OfType<string>()
.ToDictionary(
x => x,
x => (int)type.GetField(x).GetValue(this));
Then you can access the values using values["variable_name"]
Or if you don't want this, instead if you want to access them using index like [d,h] as mentioned in comments, do not store the variable names in the first place instead store the values in your array:
var type = this.GetType();
for(int d=1;d<=365;d++)
{
for(int h=1; h<=24; h++)
{
var name = string.Format("csv_{0:000}_{1:00}", d, h);
sMntHour[d,h] = (int)type.GetField(name).GetValue(this);
}
}
Ofcourse you need to change the type of sMntHour, in order to make it work.
Related
I have a simple form that accepts a number from a radio button selection (1-5) of 11 questions and posts the values into a database as varchar(10) data. I intend to send the user to a result page that lists the sum of these scores through a simple for loop, but when I try parsing the data to integer format, it simply results in zero due to error parsing. Here's an example of my code:
// Q1 - Q11 are the questions in my Db, using Model property
int sum = 0;
int temp = 0;
String question;
for (int i = 11; i >= 1; i--)
{
question = "Model.Q" + i.ToString();
temp = int.Parse(question);
sum += temp;
}
return sum;
What's strange is that if I parse them individually, such as writing:
Int32.TryParse(Model.Q5, out temp);
I am able to parse the data just fine. My console shows that the loop keeps the question variable as "Model.Qx" with quotations, ultimately resulting in 0 for the sum. I have also tried using Int32.TryParse(); for that as well and it resulted in no difference, besides handling the error.
Can a string simply not be parsed if it contains punctuation in concatenation with the i variable, or am I missing something else here? I want to avoid parsing each question individually, as it looks rather ugly in code.
Thanks in advance.
You problem is that you're trying to access a variable by using a string with the same name. This won't work, in the same way that the name gitgecko is not you.
If your model has got a number of properties with similar names, you could write a function to switch between them:
object GetQ(int number)
{
switch(number)
{
case 1: return Model.Q1;
case 2: return Model.Q2;
// etc...
}
}
Or you could change your model to store these variables in an array or list, or whatever is appropriate.
For example, if you've currently got:
class Model
{
string Q1;
string Q2:
// repeated 11 times
You could have:
class Model
{
string[] Q = new string[11];
}
which gives you the ability to do Model.Q[x]
I'm new in the c# world and I'm trying to pass an argument dynamically
So I'm doing a small addin on ms Project, and I need to do some calculation when the data is a duration or a Cost, so I have many duration field Duration1,Duration2,... and the same for cost fields
So what I'm doing is simple, I found all duration ID and I put them in my DurationList, after that I make a check, if I select only one column and the ID of this selected column is in my list, I take the name of this field and I try to pass it as an argument
This is a piece of my code, here I'm just working on the duration
using MSProject = Microsoft.Office.Interop.MSProject;
private void Application_WindowSelectionChange(MSProject.Window Window, MSProject.Selection sel, object selType)
{
MSProject.Task task = null;
List <int> DurationList = new List<int> { 188744967,...};
int value= Int32.Parse(Application.ActiveSelection.FieldIDList[1]);
Double Cost=0, CostTotal=0;
if (DurationList.Contains(value)){
string fieldname= Application.ActiveSelection.FieldName[1];
for (int i = 1; i <= sel.Tasks.Count; i++)
{
task = sel.Tasks[i];
Cost = Convert.ToDouble(task.fieldname);
CostTotal += Cost;
}
}
}
but when I tried that I get an error message: "Task" doesn't contain a definition for name and no extension method 'name' accepting a first argument of type 'Task' could be found.
So what my code is excpected to do, it gets the name of my field, it stores it in my fieldname string and after that I want to pass the content of this string as an arugment of my task.fieldname. If I used a suggested field which appear with the small wrench, like cost or duration, my code runs without issues but I need to get something more dynamic
Any idea?
Thanks
I am not sure what you are trying to do. Could you explain your intent differently?
Here are some things I noticed though:
You cannot declare and use the "+=" operator in the same line. Since "+=" is the short-hand for adding a value to the already initialized variable on the left.
i.e: x += 2; is equivelant to x = x + 2; therefor x must be initialized (have a current value) by the time you use the += operator on it. When you say double x += anyValue; that actually means x = x + anyValue and x does not yet have a value.
And as for string argument = "Duration"; are you substituting it for a string which would represent a valid double literal i.e: 1.66? I assume you are.
Without Seeing the Task class definition I cannot be sure, what is going on but I assume it is that argument is not an instance member of Task.
If I finally understand, this is how you would get the value of your Task property named "fieldname":
task = sel.Tasks[i];
var valueofFieldName = task.GetType().GetProperty(fieldname).GetValue(task, null);
Cost = Convert.ToDouble(valueofFieldName);
CostTotal += Cost;
I am just beginning with programming in c#;
I got a list of int variables that I want to sort, and find the number 1.
int Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9
do I need to do this with an array?
By using the yellow book of C# I found out how to make an array, but I can't figure out how to assign the variables to the array.
int [] Weapon_Count = new int [11] ;
for ( int i=0; i<11; i=i+1)
{
Weapon_Count [i] = ??? ;}
I hope this does make sense..
Please let me explain how to use a C#-array.
This creates an unitialized integer-array with 5 elements:
int[] a1= new int[5];
Assigning values 9,8,7,6 and 5:
(Please note that only indexes from 0 to 4 can be used. Index 5 is not valid.)
a1[0]=9;
a1[1]=8;
a1[2]=7;
a1[3]=6;
a1[4]=5;
The same can also achieved with just one line:
int[] a1= new int[] {9,8,7,6,5};
This might help you.
// Declaring the array
int[] Weapon_Count;
// Initializing the array with a size of 11
Weapon_Count = new int[11];
// Adding values to the array
for (int i = 0; i < Weapon_Count.Length; i++)
{
Weapon_Count[i] = i + 100;
}
// Printing the values in the array
for (int i = 0; i < Weapon_Count.Length; i++)
{
Console.WriteLine(Weapon_Count[i]);
}
// Same thing with a list
// Daclare and initializing the List of integers
List<int> weapon_list = new List<int>();
// Adding some values
weapon_list.Add(1);
weapon_list.Add(2);
weapon_list.Add(3);
weapon_list.Add(4);
weapon_list.Add(5);
// Printing weapin_list's values
for (int i = 0; i < weapon_list.Count; i++)
{
Console.WriteLine(weapon_list[i]);
}
// This is just for the console to wait when you are in debug mode.
Console.ReadKey();
Dont forget to include the using statment if you want to use lists (in short hand - dynamic arrays that can change in size.)
using System.Collections.Generic;
The easiest way to do this, assuming there is a finite list of variables to check, would be to throw them into a temporary array and call either Max() or Min() from the System.Linq namespace.
int maxCount = new int[] { Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9 }.Max(); // or .Min()
EDIT
If you still want to get those variables into an array, I would recommend using a System.Collections.Generic.List which has a dynamic size and helper methods such as .Add() to simplify things. Lists can also be used with Linq functions similar to the first part of my answer. See Dot Net Perls for some really good examples on different C# data types and functions.
EDIT 2
As #kblok says, you'll want to add using System.Linq; at the top of your file to gain access to the functions such as Max and Min. If you want to try using the List type, you'll need to add using System.Collections.Generic; as well. If you're in Visual Studio 2017 (maybe 2015 as well?) you can type out the data type and then hit Ctrl + . to get suggestions for namespaces that might contain that data type.
Before we start, you might edit your array to look like this:
int[] weapons = { Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9 };
This means that you've created an array called weapons and it is holding integer values.
After you did this, lets find out which element in your array has value of number one.
To find which value has value "1" we must look at each element in array, and we might do that on few ways but I would like recommend foreach or for loop, in this case I will choose foreach loop.
foreach(var item in weapons)
{
if (item == 1)
//Do something
}
This above means, loop throught all of my elements, and in case some of them is equal to number one please do something..
P.S
(I may advice to create one variable which will hold an element which has value '1' and when you find it in a loop assing that variable to that element, and later you can do whatever you want with that variable.. and if you think there will be more elements with value of number one and you need all of them, instead of variable I mentioned above you will create list or array to hold all of your elements and also you can do later with them whatever you want to.)
Thanks and if you are interested in this kind of solution, leave me a comment so let me help you till the end to solve this if you are still struggling.
Say I have an array of fixed size N, is there a way to map the elements to a list of N variable names?
I was thinking of something like:
variable1, variable2, variable3 = arrayOfSize3;
EDIT:
A few people have remarked that this would be useless and suggested that I am doing something wrong. Maybe I am, but this is a pretty common feature in dynamic languages so I was hoping C# had something elegant as an alternative.
If it helps, I can write what I need it for. I have parsed an HTML table and have an array of strings representing a row of the table. I made a class to represent the row with variables representing the data, but to store the data I have to manually set the names to each of the array elements. I know there are other ways to do this, but I was wondering more out of curiosity than anything else, what is the right way to map variables like this?
Their is no such assignment, but you can do like this:
var variable1 = arrayOfSize3[0];
var variable2 = arrayOfSize3[1];
var variable3 = arrayOfSize3[2];
Not production ready yet, but you can do this in C# 7 preview which comes with Visual Studio 15 preview. Using deconstruction matching, the following code works with Tuple
var (variable1, variable2, variable3) = tupleOfSize3;
This feature actually works with anything with a deconstructor method like this
public void Deconstruct(out T1 x1, ..., out Tn xn) { ... }
Maybe array will have this extension. Please see What's new in C# 7.0
Tuples are a set of a fixed number values, each with its own name and type. Arrays, on the other hand, are a set of a variable number of anonymous values, all of the same type. These are two very distinct forms of aggregate types, and they really serve mostly disjoint use cases.
Having said that, it is possible to deconstruct an array (in C# 7 preview which comes with Visual Studio 15 preview)! You can do it by adding your own Deconstruct method as an extension method:
class C
{
public static void Main()
{
int[] x = new int[2];
var (a, b) = x;
}
}
static class ArrayUtilities
{
public static void Deconstruct(this int[] data, out int a, out int b)
{
a = data[0];
b = data[1];
}
}
I'm trying to use something like this:
for (int i = 0; i < 40; i++)
{
string x + i = TextBox + i.Text;
}
Is there any solution for this? I want to use i as an index as if I had an array of TextBox. How can I achieve a textbox's Text property like this?
I want to create for example a string named x1,x2,x3,x4... and value of x1 = TextBox1.Text.
But I could not :(
I have TextBox1,2,3...40 and I just want to pass their text values to new string or string list ex. like x1 = TextBox1.Text, x2 = TextBox2.Text; ..... :(
You're trying to get the Text property from a collection of TextBox - which, by the way, you haven't shown us how you're getting. It's possible that you don't even have an array of TextBox.
If you do, you'd use code like this (note that SomeCodeToGetTextBoxArray() needs to be defined by you):
TextBox[] myTextBoxes = SomeCodeToGetTextBoxArray();
var arrayLength = myTextBoxes.Length;
String[] x = new String[arrayLength];
for (int i = 0; i < arrayLength; i++)
{
x[i] = myTextBoxes[i].Text;
}
What you're looking to do is have a reference to a local variable, field, or property by it's string name that you generate at runtime. The only way to do what you want is to use reflection.
There are different ways to do this depending on if the variable is locally scoped, a field member, or a property member.
Reflection - LocalVariableInfo - FieldInfo - PropertyInfo
Note that while that would be the answer to your question, it is probably better to use an array (or List<T>) and use indexes. Though, it is really impossible to know without knowing what you are trying to do fully (not just in your little snippet). But, it's more likely that an array (or List<T>) is the more correct solution.