Okay, I have this piece of code:
int arrPanelsRequired = 4;
string airport;
int arrPanelsMade = 0;
for (; arrPanelsMade <= arrPanelsRequired; arrPanelsMade++)
{
Panel arrPanelXXX = new Panel();
and I need to replace the XXX with the value of arrPanelsMade. I found several ways to name an object after a variable's value, however, I wasn't able to apply any of them here :(
I don't think it would be a good idea in general, let alone in C#. I can see many arr prefixes, which leads me to the use of an array. I think you might be looking for something like this:
int arrPanelsRequired = 4;
Panel[] panels = new Panel[arrPanelsRequired];
for (int arrPanelsMade = 0; arrPanelsMade < arrPanelsRequired; arrPanelsMade++)
{
panels[arrPanelsMade] = new Panel();
}
What you are trying to do is bad practice. It passes in weakly-typed languages, but in strongly-typed languages such as C#, variables need to be explicitly declared. This helps the compiler to catch errors that can be caused by typos or general development mistakes. For example, if you have a variable arrPanel089, how can you/the compiler know if it has been declared? Strong typing can seem like a constraint when coming from weakly-typed languages, but it is really a great tool that saves you a ton of headache as the developer.
If you want to create a set of panels, store them in an array/list/etc and access them by their index. If you want to give them a key, store them in a dictionary which allows you to access values by key instead.
You should add the panels to a List or array, and access them later by index:
arrPanel = new Panel[arrPanelsRequired];
for( int idx = 0 ; idx < arrPanelsRequired ; idx++)
arrPanel[idx] = new Panel();
You have a couple of things going on here that raise red flags. I'll digress from your question just a bit, because I think you're probably going down the wrong road in a couple of respects.
Drop the "arr" prefix, and just call your variables what they are — don't try to emulate Hungarian Notation unless you've got good reason to do so.
Consider using a while loop instead of a for loop if you're not going to perform your initialization in the loop header.
Now on to your question. No, the language doesn't work like that. Use a List<Panel> class instead. That will allow you to add more panels dynamically without having to predefine how many you want, such as in an array.
Related
May i ask if the following code i wrote is correct? Basically, i want to create an 2D array, and within each array, i want to have a list of vertices. So if tCount and pCount is 10, i would have 100 different lists storing vertices. The adding of the vertices will be done elsewhere after certain operations are done to determine which list the vertice should be added to.
List<Vertice>[,] lists = new List<Vertice>[tCount, pCount];
for (int i = 0; i < tCount; i++) {
for (int o = 0; o < pCount; o++) {
lists[i,o] = new List<Vertice>(); } }
Pardon me for posting such a simple question, because i have posted a similar qns in another forum and the replies i received kind of confused me. But thanks for reading!
Mitch Wheat- There was no error so far, but i am also not sure if the list is created properly..
Damith- I've seen that before but i do not really understand the code, so i was wondering if the code i typed was correct or not. I feel safer using a code that i understand, although i do understand the benefits of using a 1-liner.
Oberdan Nunes- I need it to be in a 2D array, as it is related to another 2D array of data which i have.
Given the following code snip:
using (var reader = cmd.ExecuteReader())
{
while(reader.Read())
{
var count = reader.FieldCount; // the first column must be name all subsequent columns are treated as data
var data = new List<double>();
for (var i = 1; i < count; i++)
{
data.Add(Convert.ToDouble(reader[i].ToString()));
}
barChartSeries.Add(new ColumnBarChart.ColumnChartSeries((string)reader[0],
data));
columnChart.xAxis.categories.Add((string)reader[0]);
}
}
Is there an easy way to eliminate the for loop? Perhaps using linq?
reader[0] will always be a string
reader[0+?] will be a double
I want to pull all the doubles into a list if possible.
Speed is somewhat of a concern I suppose.
Then you're focusing on entirely the wrong problem.
Out of the things you're doing here, looping is the least inefficient part. More worrying is that you're converting from a double to string and then back to double. At least fix your code to:
for (var i = 1; i < count; i++)
{
data.Add(reader.GetDouble(i));
}
You could create the list with the known size, too:
List<double> data = new List<double>(count - 1);
Even then, I strongly suspect that's going to be irrelevant compared with the serialization and database access.
Whatever you do, something is going to be looping. You could go to great lengths to hide the looping (e.g. by writing an extension method to iterate over all the values in a row) - but really, I don't see that there's anything wrong with it here.
I strongly advise you to avoid micro-optimizing until you've proven there's a problem. I'd be utterly astonished if this bit of code you're worrying about is a bottleneck at all. Generally, you should write the simplest code which achieves what you want it to, decide on your performance criteria and then test against them. Only move away from simple code when you need to.
The only way I can see to remove the forloop is to use Enumerable.Range.
But anyway you could do something like:
var data = new List<double>(Enumerable.Range(1, count).Select(i => reader.GetDouble(i)));
But I see no benefit to this approch, and it just makes the code unreadable
I dont think you can loop on it because
public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord
and this class does not implement IEnumerable
You could use the LINQ Cast method to get something you can use other LINQ methods on, but I agree with the other posters - there's nothing wrong with a for loop. LINQ methods will just use a less efficient loop in the background.
I believe this should work, but haven't set up a data set to test it.
reader.Cast<Double>().Skip(1).ToList();
The MSDN document that I am trying to follow is located here. Basically I am trying to figure out in C# how to read that pointer into a list of the DHCP_OPTION_DATA structures.
I have the following code but I don't think that it is the proper way to do this.
DHCP_OPTION_ARRAY optionArray = (DHCP_OPTION_ARRAY)Marshal.PtrToStructure(options, typeof(DHCP_OPTION_ARRAY));
List<DHCP_OPTION> allOptions = new List<DHCP_OPTION>();
for (int i = 0; i < optionArray.NumElements; i++) {
DHCP_OPTION option = (DHCP_OPTION)Marshal.PtrToStructure(optionArray.Options, typeof(DHCP_OPTION));
allOptions.Add(option);
optionArray.Options = (IntPtr)((int)optionArray.Options + (int)Marshal.SizeOf(option));
}
Since I can't Marshal the pointer into a generic list collection I tried this way. My problem is that I am getting skewed results based on how much I increase the IntPtr to. Initially I was doing this.
optionArray.Options = (IntPtr)((int)optionArray.Options + (int)Marshal.SizeOf(typeof(DHCP_OPTION_DATA)));
However, I then realized that the next element would be located after the size of the actual option.
So the question still remains, how do I Marshal a Ptr to a list of structures?
EDIT 1
I posted the wrong article it is fixed now.
EDIT 2
Although both answers were great, I chose the answer to my problem because it addressed my lack of understanding of how the data was being handled on the back end of marshaling the information.
Is the first option object you get correct?
If so, the reason for the rest being skewed most likely is the alignment of the structure.
You could try to find the correct alignment, for example:
var offset = (int)Marshal.SizeOf(typeof(DHCP_OPTION_DATA));
var alignment = 4;
var remainder = offset % alignment;
if(remainder != 0)
offset += alignment - remainder;
optionArray.Options = (IntPtr)((int)optionArray.Options + offset);
Here is a paper Jason Rupard wrote using the DHCP_OPTION_ARRAY...
http://www.rupj.net/portfolio/docs/dws-writeup.pdf
Looks like he has everything you need and more... :)
Although looking at it you could define the structure a little differently and have it automatically turned into an array upon deserialization if you get the Pack attribute right.
At my last firm, I came across what seemed like a really clever way of creating constants for the indices of certain pieces of a delimited string, or columns in a SQL table, but I've long wondered if there's a performance or other flaw I didn't catch.
For example, if there were five data fields in a single delimited string containing address information, you might see the following:
const int INDX_NAME = 0;
const int INDX_ADDR = INDX_NAME + 1;
const int INDX_CITY = INDX_ADDR + 1;
const int INDX_STATE = INDX_CITY + 1;
const int INDX_ZIP = INDX_STATE + 1;
That way, if in the future, the program needed to separate what could be two lines of an address between the name and city (say, street address on one line, suite number on the other), all the programmer would have to do is add the line
const int INDX_ADDR2 = INDX_ADDR + 1;
and change the line creating INDX_CITY to
const int INDX_CITY = INDX_ADDR2 + 1;
In short, this seemed like a really clever way of handling column/piece index lists that could change, especially if the list was 50+ items, and you need to add something at index number 3. However, I wasn't sure how much this could start affecting performance as the list starts getting large, or whether there was some other inherent flaw I wasn't seeing.
Any thoughts? Is there something that makes this lazy programming instead of clever?
Thanks.
-EDIT-
I can see where the value of enums would be given the responses I've been getting, but I'm concerned that they'd only be useful if every field I'm using is exactly 1 spot away from every other. What if I'm using pieces of some data storage that other programmers are also referencing, but I only care about a subset of the total fields, so I need to skip blocks of fields that I don't care about.
For example, I'm using 100 data fields from a delimited string that 300-fields long, but my application doesn't care about fields 1-4 (array counting). Is there a clean way to use enums to replace
const int INDX_RECORD_ID = 0;
const int INDX_DATE_UPDATED = INDX_RECORD_ID + 5;
const int INDX_USER_UPDATED = INDX_DATE_UPDATE + 1;
...
?
You should really use an enum here. They are designed for exactly this type of situation:
public enum MyEnum
{
NDX_NAME,
INDX_ADDR,
INDX_CITY,
INDX_STATE,
INDX_ZIP
}
Adding values (to any position) will update all of the indexes accordingly.
Using an enumeration will have several advantages: (not an exhaustive list)
You could have a parameter to a function or a variable typed to the enumeration, rather than an index. This helps make the intent clearer to other coders then knowing that, "This parameter needs to be given one of the constants in this other class."
You don't need to worry about making a mistake where you don't add one to the previous constant. I could easily see that happening when you add in a new item in the middle, or just as a copy/paste error.
You can use other enum tools, such as the ability to get the string value of an enum (as well as the integer value) for easier displaying, you can use reflection to iterate the possible values, you can parse a string or an integer into the appropriate enum value, etc.
As for performance, the values (for both an enum and your constants) will be evaluated at compile time, not runtime, so at runtime it won't have any additional cost over manual numbering.
No, it's not "lazy". I think it's simply good practice. And it incurs no runtime penalty because const fields must be compile-time constants.
If we know that int n = myArray.Length = myList.Count
Then, when we need to use this value to represent the array/list length, which one is best to use?
e.g. do we use var x=n*2 or var x=myArray.Length*2 or var x=myList.Count*2
The equivalent question is like, would it be more efficient to directly use n instead of referring to the member property of an object?
It sounds like you're asking the following
If we know that a local n == myList.Count should I use n over myList.Count because it's potentially more efficient?
It's true that a local lookup is generally more efficient than a member access. However the difference is very small and something I wouldn't concern myself with when writing a program.
Instead focus on writing the most readable code possible. Don't concern yourself with micro optimizations like this because they almost certainly won't matter. You're much more likely to find your program bottle necked at I/O, or choice of data structures than a field vs local time access difference.
If you're going to use a variable to store the length of an array, make sure that you're using a more suitable name than "n". For example, you may want to use:
int arrayLength = myArray.Length;
However, I prefer to use myArray.Length throughout my applications because I know exactly what it's referring to. At the end of the day, though, I suppose this is just personal preference.