|
Jasmine,
The use of a named constant is preferred, even if it will be used only once.
Will the value from the AppSettings be the same for every instance of MyClass?
If so, then Option 2a with the addition of static readonly :
public class MyClass {
private const string SettingKey = "SomeSettingKey";
private static readonly System.String SettingValue =
System.Configuration.ConfigurationManager.AppSettings[SettingKey];
}
If you need the SettingValue to match the AppSettings value when each instance is created, then I'd scope as much as possible within the constructor:
public class MyClass {
private readonly System.String SettingValue;
public MyClass() {
const string SettingKey = "SomeSettingKey";
this.SettingValue = System.Configuration.ConfigurationManager.AppSettings[SettingKey];
}
}
|
|
|
|
|
If I had given you the real name of the class in the code I'm working with it would be obvious, but yeah the setting value and the key can not change for the life of the application. In fact, I think the class might actually be a singleton for our app but I need to discuss that first with the previous developer. Once it's read, it's always the same, so I think the "static readonly" is the right modifier for it. Thanks for the help, that makes a lot of sense
Also, I know it's excessively trivial, but my objection to the named constant is - wouldn't that take a memory location we don't need to use? The compiler doesn't know that it will only be used once, so it's going to stick that in a memory location, right? So then, what we have is two instances of the string in memory, right? Once in the code and once in the heap? If you do this a thousand times, you waste a K of memory. I know, I know, who cares about a lousy 1K of memory...
(programmers not giving a crap about saving 1K of memory when they can is probably why my favorite pinball game no longer works well on my tablet, and I find it annoying. I find the bloat in modern software really annoying, even when it doesn't cause bugs or performance issues)
|
|
|
|
|
I'd probably use a const, but have you considered using an enumeration?
Jasmine2501 wrote: wouldn't that take a memory location we don't need to use?
Possibly, but that kind of thinking can lead to define s -- at one place I worked (in C) the standard was to put such values in define s to "save space".
|
|
|
|
|
But that doesn't really save space, right? Using #define puts the literal value into your final code, right? So, if it's used in multiple places, you're actually wasting memory (code size) with #define, but only if the value is used more than once.
|
|
|
|
|
The const for the string is really the better way.
Remember that in c#, strings are invariant. So the compiler can and will automatically use the same actual string no matter how often it is referenced. Referencing a string const multiple times, or using the identical string literal multiple times is the same. Only one string will be stored in the program and all of the references to it will be to the exact same object.
So why did I say the const for string is better?
For maintainability. The name of the const can (should) be based on the functional use of the value, and can be updated in a single location, guaranteed to affect all uses. With string literals it is easy to miss one
|
|
|
|
|
Yeah I agree, I just thought since the string was being created as an object, it's going to get stored in memory somewhere, in addition to the place where it's stored in the code.
|
|
|
|
|
But no matter how you code it, const or literal, it must be an object at run-time!
The compiler arranges for it to always be the same object.
This is from the c# spec document:
For instance, the output produced by
class Test
{
static void Main() {
object a = "hello";
object b = "hello";
System.Console.WriteLine(a == b);
}
} is True because the two literals refer to the same string instance.
|
|
|
|
|
Well no, if you stick it in there as a literal, it's only stored once, in the code.
Unless you're saying...
Console.Writeln("Hello World");
...creates a string object in memory?
Your IF is true above because you used the equivalence operator, which compares the values, not the pointers.
|
|
|
|
|
|
Regarding == of the strings, the same result (true ) is displayed if the comparison is changed to: object.ReferenceEquals(a,b)
They really are the same object.
|
|
|
|
|
It's probably personal. I prefer option 2, because it does not allow for confusion and keys rarely or never change name.
|
|
|
|
|
There are a number of issues here, when speaking about a generic answer rather than one strictly limited to the examples given, with one potentially important one so far not mentioned: the assignment will happen at different times.
In your first example, SettingValue is assigned after all base constructors have been executed. In your second example, which uses field initialisation, SettingValue is assigned before any base constructors have been executed.
This may affect what exceptions are thrown on construction errors. For instance, a ConfigurationErrorsException will be thrown if the value is not found. In the first example, you can catch this in the constructor and set a default, or give a more detailed exception. In the second example, you can't, and will have to rely on it being caught outside the class.
And if a base constructor would also throw an exception, in your first example this is what will be thrown, while in the second example it's the ConfigurationErrorsException that will be thrown.
|
|
|
|
|
Orjan Westin wrote: a ConfigurationErrorsException will be thrown if the value is not found
Not in the AppSettings section; if the specified key doesn't exist, it will return null .
However, you can get a ConfigurationErrorsException if the configuration file is corrupt.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Oh, I wasn't aware of that. Thanks.
|
|
|
|
|
Thanks! This is what I'm looking for. I didn't think about the order of things, that might be important. Also thanks for giving me the names of the processes, I had never heard "field initialization" before.
|
|
|
|
|
Option 1 because if it fails then the cause of the failure is less likely to be confusing.
And yes the code can fail.
|
|
|
|
|
Any code can fail, but if this fails, it's a fatal error and if the application blows up, that's fine.
|
|
|
|
|
Hi All;
I have a large dataset stored in a CSV file (about 40,000 Rows and 10,000 Columns). I need to load it into a C# Windows application. So, any idea to do this. I tried different code, but some are able to loao 40,000 R * 255 C, and other codes are able to load 5,000 R and 10,000 C.
Thanks
losan1985
|
|
|
|
|
It's probably going to take rolling your own custom class to hold it all. I don't know of anything "off-the-shelf" that will hold 10,000 columns. Frankly, I've never even HEARD of such a wide CSV file ever being used.
It shouldn't be very hard at all to create a List<list<int>> or whatever your item data type is. Basically, a List of List of Integers.
|
|
|
|
|
You probably can't load it all at once (at least in a 32-bit OS). 40,000 x 10,000 = 400,000,000 bytes if each cell is 1 byte. If you assume an average of 16 bytes (since you didn't say) per cell, thats 6,400,000,000 bytes = 5GB of data. You only have 2GB of address space for your application. You can do it on a 64-bit OS though.
With that being said, I doubt you really need 40,000 x 10,000 cells loaded in memory at once. What is a person going to do with all that data?
You might want to consider loading only the portion you need.
|
|
|
|
|
What is your actual requirement? You are loading this data for a reason. What is that reason? For instance, are you performing some calculation on certain columns? By breaking down your requirements, we can work out a practical solution.
|
|
|
|
|
yes, this may solve your problem....
|
|
|
|
|
As POH has said your design has to be wrong for this to be a valid requirement. Go back and look at how the CSV was created, why does it require 10k columns (what a ridiculous number). Can your source break it up into more swallowable chunks. Do you need all 10k columns.
Can you load and process 1 row at a time, presumably you want to dump this into some more reasonable format.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
You'll need to build in a sort of paging mechanism that only loads that part that is shown on the screen.
|
|
|
|
|
As Sledgehammer01 says, that's an unreasonably large amount of data for most purposes. It's 400 million cells and so you're talking about GB of memory, depending on exactly what's in there. What do you want to do with this dataset? You almost certainly want a load-on-demand adapter of some kind, so you can run through the data without actually having it all in memory at once.
This library is rather good; I used it in a real application (though not dealing with massive datasets) without problem.
|
|
|
|