An Office Add-In I'm developing is going to have a few dozen 120-length double arrays in it (statically). I could just make a class with a bunch of static member arrays and use array initializers, but this seems a little ugly. It makes sense to me that I'd be able to store these in a Resource file, but it doesn't really have any options that fit. The closest option is "text file" but then I'd either have to parse each array each time I wanted to use it or build a lazyloader (which seems just as inelegant). Is there a better option?
(For the curious, the arrays are mortality tables.)
I would personally make them static members of a static class and put the data in an ini file. Add a bool to the class to indicate whether or not the arrays have been initialized (or you could do this on an array by array basis) and in all files you access the class do a check to make sure it's initialized, if not, call the method which reads the file and loads data into the arrays. The method to load the data really shouldn't be that messy, and it's a fairly trivial operation.
This method also gives you namespace access to the data (global if you have the proper using statements/build dependencies).
Why not use a string resource. Read that string, seperate it on the comma's and parse each number. When you have read the string, all seperating and parsing can be done in one line of LINQ.
Example:
string myResource = "1, 2, 3.4, 5.6";
double[] values = myResource.Split(',').Select(Convert.ToDouble).ToArray();
Otherwise you could serialize your array with doubles once to a binary file and deserialize it in your code.
If parsing is your main concern (because of speed), store the result locally in a private cache. Each time the array is requested, just make a clone of it.
Related
I am wanting to create a 'dictionary' of strings, however I have only ever learned how to use strings to reference what I want in a dictionary. I want something with more auto-correct (as typos can happen in a large table of strings), which is why I want to know how to hard-code. (The value of the strings will be retrieved from a text file, like JSON).
I notice that Microsoft uses some type of hard-coding in their String Resource File.
So instead of doing:
string result = strings["Hello"];
I wish to do this:
string result = strings.Hello;
The only thing I can think of is to use some external tool that creates an enum/struct script with the values from the text file. Is there a better option, perhaps one built into .NET?
Edit: I think 'strongly-typed' would be a better description over 'hard-coded'.
Edit 2: Thanks for all the comments and answers. By the looks of it, some code-gen is required to fufil this result. I wonder if there's already any tools out there that do this for you (I tried looking but my terminology may be lacking). It doesn't seem too difficult to create this tool.
There are compiletime constants and runtime constants.
Your wish for Autocrrection/Intellisense support requires a compile time constants. Those are the only ones Intellisence, Syntax Highlighting and the Compiler double check for you.
But your requriement of having the values generated from a 3rd party textfile, indicates either a runtime constant or some automatic code generation. Runtime constants would take away the Editor support. While Code generation would run into issue with the Editor only having a old copy of the file. And a high risk of breaking tons of code if a string in that one file changes.
So your two requirements are inherently at odds. You need to have your cake and eat it too.
Perhaps my primitve solution to the Enum/ToString() problem might help you?
Enumeration are for most parts groups of constants, and integer ones by default. With added type checks on assignments. That makes them a good way around Primitive Obsession. You reference a value from the group like you would any constant, readonly static field or readonly property. (There is other advantages like Flags, but I doubt they mater here).
While Enums have a string you could use for display and input parsing - the one you use in sourcecode - that one is absolutely not suited for display. By default they are all-caps and you would need to support Localisation down the line. My primitive Solution was a translation layer. I add a Dictionary<someEnum, String> SomeEnumStringRepresentation. This dictionary can be generated and even changed at runtime:
I need to display any specific value, it is SomeEnumLocalisation[someEnum]. I could add a default behavior to just ToString() the compiler representation of the Enum.
I need to parse a user input? Itterate over the values until you find a match, if not throw a ParseException.
I get to use compile time checks. Without having to deal with the very inmutable compile side strings anywhere else. Or with my code side strings changing all the time.
i am not quit understand what out put you want , bu I am just throwing an idea to here - how about to extend the class string and add your own methods to it ? so when you use strings.Hello it will return what you wanted?
example :
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods
I've come across this problem often, but I haven't found a satisfying solution yet.
I am implementing a reader for savegames (but it could also be applied to other types of files). Depending on the version, there are some added entries, but the order always remains the same. Therefore I created a class:
public class Entry<T> {
public T Value;
public readonly FileVersion MinVersion;
public Entry(T v = default(T), ScenarioVersion m = FileVersion.V115) {
Value = v;
MinVersion = m;
}
}
Now, you guess, I want to write those entries with as less code as possible. I want to write the line if (version >= MinVersion) { /* write data */ } only once. The Entries can be primitive types or objects, which is the problem...
Should define an interface and implement it for every needed primitive type as a wrapper? Or is there a more elegant solution?
(Looking at the comment for specific questions.)
Some values are only written if a certain condition is met.
Are these conditions known at the time the file is read/written or, when read, are they based on other data in the file? If the former (already known), pass in a Func<bool> that must evaluate to true for the read or write operation to occur. The caller can supply an appropriate delegate or lambda method that makes the decision. You mention a minimum version in the question. I assume it is an example of this.
If the latter (values are read/written based on other data in the file), this is a wider question. If the decision can be made on data earlier in the file or in known places, load it and pass the appropriate arguments into the Func. Otherwise, you may need to look at more complex parsing mechanisms but I think this not what you are asking.
It is not a static structure and contains some things like struct { int len; char[len]; }.
.Net offers multiple ways to serialize objects but I suspect you want to read/write in a defined format, such as one that stores a string as a length followed by 8-bit characters. If the .Net mechanisms do not do what you want, you may have to write your own. See Byte for byte serialization of a struct in C# for more information on this, including the use of Marshal to get the underlying bytes of a primitive.
Also, more for reference, if you want to avoid writing primitive types out, you could use public class Entry<T> where T: class.
In a Unit Test (in Visual Studio 2008) I want to compare the content of a large object (a list of custom types, to be precise) with a stored reference of this object. The goal is to make sure, that any later refactorings of the code produces the same object content.
Discarded Idea:
A first thought was to serialize to XML, and then compare the hardcoded strings or a file content. This would allow for easy finding of any difference. However since my types are not XML serializable without a hack, I must find another solution. I could use binary serialization but this will not be readable anymore.
Is there a simple and elegant solution to this?
EDIT: According to Marc Gravell's proposal I do now like this:
using (MemoryStream stream = new MemoryStream())
{
//create actual graph using only comparable properties
List<NavigationResult> comparableActual = (from item in sparsed
select new NavigationResult
{
Direction = item.Direction,
/*...*/
VersionIndication = item.VersionIndication
}).ToList();
(new BinaryFormatter()).Serialize(stream, comparableActual);
string base64encodedActual = System.Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length);//base64 encoded binary representation of this
string base64encodedReference = #"AAEAAAD....";//this reference is the expected value
Assert.AreEqual(base64encodedReference, base64encodedActual, "The comparable part of the sparsed set is not equal to the reference.");
}
In essence I do select the comparable properties first, then encode the graph, then compare it to a similarly encoded reference.
Encoding enables deep comparison in a simple way. The reason I use base64 encoding is, that I can easily store the reference it in a string variable.
I would still be inclined to use serialization. But rather than having to know the binary, just create an expected graph, serialize that. Now serialize the actual graph and compare bytes. This is only useful to tell you that there is a difference; you'd need inspection to find what, which is a pain.
I would use the hack to do XML comparision. Or you could use reflection to automaticaly traverse object properties (but this will traverse ALL of them, also some you could not want to).
I would make each custom type inherit IComparable, and provide equality methods, that compare each custom types, as well as making the main class ICompareble, You can then simply compare the 2 objects ( if you have them in memory when running unit tests) If not then I would suggest either serializing, or defining constants which you expect the refactored object to have.
Let's say, hypothetically (read: I don't think I actually need this, but I am curious as the idea popped into my head), one wanted an array of memory set aside locally on the stack, not on the heap. For instance, something like this:
private void someFunction()
{
int[20] stackArray; //C style; I know the size and it's set in stone
}
I'm guessing the answer is no. All I've been able to find is heap based arrays. If someone were to need this, would there be any workarounds? Is there any way to set aside a certain amount of sequential memory in a "value type" way? Or are structs with named parameters the only way (like the way the Matrix struct in XNA has 16 named parameters (M11-M44))?
What you want is stackalloc; unfortunately, you can only use this in unsafe code, which means it won't run in a limited permissions context.
You could also create a struct with the necessary number of variables in it for each element type, but you would need a new type for each size of 'array' you wanted to use
The closest thing I can think of to a stack-based array would be a manually-nested structure; for an array of size N^M, the code size would be O(MN) and the access time O(M); one could scale M and N as convenient (e.g. one could handle a 4096-element array as six-deep nested 4-element structures, four-deep nested 8-element structures or three-deep nested 16-element structures, two-deep nested 64-element structures, etc.) If one wanted to do three-deep nesting of 16-element arrays (probably the most practical trade-off) one would define a 16-element structure with fields f0 through f15, and an access method using switch/case to select an element. One could then define a 16-element structure of those, a 16-element structure of those, etc.
In general, using a standard Array is apt to be better than using value-type structures to mimic arrays, but there are times when having an array-ish thing as a value type would be advantageous. The advantages of value type arrays would tend to be limited in .net, however, by some limitations in its handling of manipulating value types by reference. While it would be nice if one could simply access element 0x123 from an array described as above by writing "MyArrayishThing[1][2][3]", that would be inefficient for reading and ineffective for writing (since the subexpression MyArrayishThing[1] would make a copy of structures holding 256 elements of the array). Instead, what's necessary is to pass MyArrayishThing[1] by reference to a routine that can access element 2 of that and pass it by reference to a routine to access element 3 of that. It's possible to do that efficiently, but the code ends up looking rather nasty.
Does it make sense to implement a copy method on an immutable type, returning a new instance? Or should it just be the current instance?
I thought the type doesn't change anyway so why copy? Like no one copies the number 5, right?
There are certain cases where it makes sense. Java strings are a good example. When a string is created in Java, it has a reference to a backing array of characters (a char[]). It knows the offset into the char array, and the length of the string. When you create a substring, that refers to the same backing array. Now consider this code:
String x = buildVeryLongString();
String y = x.substring(0, 5);
// Use y a lot, but x is garbage collected
The fact that y is still in the system means that the original char[] used by x is still required. In other words, you're using more memory than you have to. If you change the code to:
String x = buildVeryLongString();
String y = new String(x.substring(0, 5));
then you'll end up copying the data to a new char[]. When x and y have rougly the same lifetimes this approach wastes memory (by having two copies) but in the case where x is garbage collected before y, it can make a big difference.
I've run into a similar example with strings in real life, when reading words from a dictionary. By default, BufferedReader.readLine() will use a buffer of 80 characters for a line to start with - so any (non-empty) string returned by readLine() will refer to a char[] array of at least 80 characters. If you're reading a dictionary file with one word per line, that's a lot of wasted space!
This is just an example, but it shows the difference between two immutable objects which are semantically equivalent in terms of what you do with them, but have different characteristics in other ways. That is usually at the heart of why you'd want to copy an immutable type - but it's still a pretty rare thing to want to do.
In .NET, strings are stored somewhat differently - the character data is held within the string object itself instead of in a separate array. (Arrays, strings and IntPtr are the only variable-size types in .NET, as far as I'm aware.) However, the "buffer" in the string can still be larger than it needs to be. For example:
StringBuilder builder = new StringBuilder(10000);
builder.Append("not a lot");
string x = builder.ToString();
The string object referred to by x will have a huge buffer. Changing the last line to builder.ToString().Copy() would make the large buffer eligible for garbage collection immediately, leaving a small string instead. Again, doing this unconditionally is a bad idea, but it can be helpful in some cases.
Technically, an integer is a value type so it is copied constantly. :)
That said, making a copy of an immutable object doesn't make sense. The examples of strings provided by others seems to be a band aid on abstraction leakage by those classes.
I'll assume we mean objects (classes), since it is a moot point for structs.
There are a few dubious reasons for cloning an immutable object:
if the object is remoted, and you want a local copy (although in this case you presumably couldn't use an instance method on the object itself, as that would also return a remoted instance - you'd have to have the clone method local (non-remoted))
if you are hugely worried about reflection (even readonly fields can be changed by reflection) - perhaps for some super-security conscious code
if some external API (that you can't control) uses reference equality, and you want to use the same "value" as two separate keys - OK, I'm stretching things now...
If we extend the discussion to consider deep cloning, then it becomes more reasonable, since a regular immutable object doesn't imply that any associated objects are also immutable. A deep clone would fix this, but is a separate consideration.
I think maybe the remoting scenario is the best I can do...
Well Java's String class has this:
String(String original)
Initializes a newly created String object so that it represents the same
sequence of characters as the argument; in other words, the newly created
string is a copy of the argument string.
and .Net's has the Copy() method which does the same.
Both frameworks were designed by people who are smarter than I am, so there must be a good reason - someone at sometime needs strings that are different reference-wise, but have the same value.
I'm just not sure when that would be...
Does it make sense to provide a 'Copy'
operation on an immutable object?
No.
(There is lots of other interesting discussion in the other answers, but I thought I'd provide the short answer.)
If said object needs to implement an interface that requires a Clone() method (or moral equivalent), it is fine to 'return this'.
One of the advantages of immutable types is that they can be interned (e.g., Java strings). Certainly you shouldn't make extra copies if you can avoid it.