Values storable in Excel - c#

Good evening!
Which types of values can be directly stored into an Excel worksheet using Range.Value2 and how do I quickly check if a particular value can?
Suppose I have an array of objects, perhaps multityped (e.g. one int, one double and one Foo stored in an object[]).
If I shall choose a range of width 3 and try to store this array using Range.Value2, this will result in an exception (of course Excel doesn't know what is a Foo).
I came up with an idea of checking each value in the array, and, if it's not storable, convert it to its string representation using ToString(). But how do I check if it's initially storable?
It would be horrible to end up doing something like that:
public bool storable<T>(T value)
{
return value is int ||
value is uint ||
value is short ||
value is byte ||
...
value is string;
}
...especially knowing that each is will cast the variable to the tested type and seriously affect performance.
On the other hand, I can't afford pre-casting each value to the string type as I sometimes want to be able to do graphs and diagrams with numeric values, not strings.
Can you tell me I am mistaken or offer me any solution to the problem?
Thank you!

I think you're going to have to do what you're unkeen to do (all the "is" checks), unless you can somehow make your input array a bit more strongly typed. Your best bet might be just to order the casts such that the most common ones get hit first.

Related

Testing database field types for compatibility

I have some generic database routines. One that I make use of quite frequently is based on code similar to this code, but for an OleDbDataReader, not the generic IDataReader from that code.
I was playing around with this, and decided to test what would if I tried to (say) retrieve a value from a field, where I had input the incorrect type. Eg: I try to get a double value from a database column that is actually an integer:
reader.GetValue<double>("Column_that_is_Integer_Type");
...and, unexpectedly, it seamlessly converts the database column integer value to a double. Hmm. OK - I get a usable value back, but what about other conversions?
reader.GetValue<bool>("Column_that_is_Integer_Type");
This returns true. Not exactly what I want, and I get no error.
reader.GetValue<DateTime>("Column_that_is_Integer_Type");
This one at least throws an InvalidCast Exception.
Because of all this, I added the follow type checks to the code:
if (theReader.GetFieldType(fieldIndex) == typeof(T))
{
//Carry on...
}
else
{
//Raise an error
}
I think this is the safest way of preventing issues, but was wondering if there is a somewhat 'generic' compatibility check that can be performed? My onward use of a given variable probably won't care whether '39.5' retrieved from a database that stores it as a double is passed around as a decimal, but it will certainly care if it is being passed around as a bool.
My default position will be to throw an error if someone gets the column data type wrong, but I was interested enough to ask the question: Is there a robust method for checking whether type conversions preserve appropriate data integrity?
Eg. Integer type converted to Double: OK. Double converted to Integer: Nope.
Double type converted to Decimal: OK. Double converted to DateTime: Nope.
I think I've answered my own question, but interested in opinions.

How to handle null when overloading operator + for a class value object?

I want to have to have a value object that represents length. I would prefer to use a struct given that it is a value type, but since zero length does not make sense I am forced to use a class. Adding two lengths together seems like a reasonable operation, so I want to overload the + operator. I am curious though, how should I handle adding null?
Adding null to an existing string returns a string with the same content as the existing string. Adding null to a int? that has a value returns null.
I can see a case where adding nullto an existing length simply returns a new length with the same value as the existing length. At the same time, I can see a case where adding null would be considered a bug. I have been trying to find some guidance but have not been able to find any. Is there a common guideline for this or is it different for each application?
I would highly recommend using struct for your length, and treating the default representation as zero length.
since zero length does not make sense I am forced to use a class
It is up to your code to treat the default representation of length struct as a representation of some specific length. In addition to treating it as zero length, you have at least two options:
You can treat default length as an unknown, in which case any operation with it would produce an unknown, or
You can treat it as a "trap representation" of length, in which case any operation with it would produce an exception.
It is probably a design mistake to not treat zeros in a uniform way with all other numbers. Specifically, zero length may become handy when you subtract length values, because subtracting two values of equal length would have nothing to produce.
As far as "unknown" length is concerned, using struct gives you a convenient standard representation of Nullable<length> immediately familiar to users of your length structure.
Simple Answer:
if your allowed to add nulls in your system then you should probably keep the existing value and treat it like a 0 like so:
public static NullNumber operator+ (NullNumber b, NullNumber c) {
return (b ?? 0) + (c ?? 0);
}
Advanced Answer:
You are probably correct about length not making sense at 0 and you are right about adding nulls seems like a bug
I can't see where the field is populated but I suspect either:
you don't have a constructor that requires you to pass in a length if it's required.
Or you have a faulty class that sometimes has a length and sometimes meaning it sounds closer to 2 classes
Strictly speaking, a null length doesn't exist in reality, everything has length. Getting a null return or a NullReferenceException when working with your struct would lead me to think I messed up the constructor or instantiation. In other words, the null reference would be employed in the scope of the application and not exposed to the client.
struct length = new MyStruct(); //no!
struct length = new MyStruct(double feet, double inches) //better...
struct length = 34.5; //ok...

How to "FillMissing" with a value of 0

I'm reading some data in from a CSV file into a frame and I want to replace the blanks in a certain column with zeros. However, when I do FillMissing(0), the series returned still shows the values as blanks. I'm guessing it's because Deedle inferred the type of the column to be int and not int? and thus a zero is equivalent to missing.
Is there a way to either use FillMissing to do what I want, or alternatively, override the type inference so it treats this column as an int??
The FillMissing method will fill all missing values in columns that have the same type as the value provided. This is a bit confusing and we're looking for better ideas how to do this!
This means that FillMissing(0) will only fill columns with integers. You can try calling FillMissing(0.0) to handle floating point columns or FillMissing(0.0M) to handle decimals.
The fact whether a value is nullable does not matter - Deedle handles missing values directly and so column loaded from a CSV will never have a type int?

In C# comparing strings to ints

I'm working with the Umbraco CMS which holds lots of data as strings.
Sometimes I need to compare a stored value string value (which is an int stored as a string) to an enum, but is it best to compare them as strings:
if ( stringValue == ( (int) Enum.Option ).ToString() ){
}
Or to parse and compare as ints:
if ( int.Parse(stringValue) == (int) Enum.Option ){
}
Or does it just not matter either way!
You should compare data in its native/canonical form. So use integers. Performance is usually a second-order concern in such cases. Correctness is first.
Maybe you want to try to use Enum.Parse?
enum MyEnum
{
Option,
Option1 = 1,
Option2 = 2
}
string stringValue = "0";
if((MyEnum)Enum.Parse(typeof(MyEnum), stringValue) == MyEnum.Option)
{
//Do what you need
}
Note:
The value parameter contains the string representation of an enumeration member's underlying value or named constant, or a list of named constants delimited by commas (,).
So stringValue can be "Option" or "0".
Its even better if you will compare enums.
For the sake of code readability, I'd choose the second approach: it makes clear beyond doubt that your string is expected to contain an integer in that particular context, and you're treating it as such.
Second approach would also allow you to handle error cases more deeply (what if your string isn't an integer ? Second block would throw, first one would silently act just like your data was different from the enum).
Also, as already stated, comparing integers is always better performance-wise than comparing strings, but I believe there wouldn't be much real-world difference in this case.
Casting from int to an enum is extremely cheap... it'll be faster than a dictionary lookup. Basically it's a no-op, just copying the bits into a location with a different notional type.
Parsing a string into an enum value will be somewhat slower.
from this SO answer.
If you want to check the validity, you can use
int value;
Option option;
if (int.TryParse(stringValue, out value) &&
Enum.IsDefined(typeof(Option), value)) {
option=(Option)value;
}

Does textbox save an all number text as a long or string?

I have a brief discussion with my teammate regarding this. He says, if I enter a number in textbox, and try to use the value later on using textbox.text or val(textbox.text), I will not need to parse the value to integer. According to him, if the text attribute value is all number, you can directly get the value as integer, instead of string.
So, if I have textBox1.Text = "12345", then next time, if I use, intABC = textBox1.Text, it will not throw an error. Is it right? Does C# or other .Net language does this implicit conversion? Also, will the code store "12345" as string or integer? And how much memory will this value take, 5bytes for 5 characters or 2bytes for an integer?
TextBox.Text keeps the text as a simple string, it doesn't care about the real "meaning" of the string.
Then, if you want to have your number back, you need to parse the string, hence neither implicit nor explicit cast to int is allowed (or better, it will throw an exception if you do it...).
About the size, that text is stored as an UNICODE (UTF-16) string, hence from 2 to 4 bytes per character (depending on the character).
You can easily measure the size (just the size of the string, without the overhead due to reference size etc.) using the following code:
int numBytes = Encoding.Unicode.GetByteCount(stringToMeasure);
To find more info about strings, unicode and encodings have a look here, here or here .
your friend is wrong, it will make the compiler unhappy, the compiler won't even convert it automatically for you. Text property of a TextBox is of type string. check this
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.textbox.text.aspx
As to your question of other languages; if 'option strict' is not enabled, VB.NET will allow this. It will also allow this assignment if the input is not entirely numeric however, resulting in a runtime exception.
If you know you will only use numerical values, try using a NumericUpDown control.
You could then get/set the numerical value (decimal) by using the Value property.
A NumericUpDown control contains a single numeric value that can be incremented or decremented by clicking the up or down buttons of the control. The user can also enter in a value, unless the ReadOnly property is set to true.

Categories