How can I check for β€œsafe” conversions between value types in .NET?

Back to basics ...

For reference types, you can do the following:

SomeType someObject = firstObject as SomeType; if (someObject == null) { // Handle the situation gracefully } else { // Do stuff } 

For value types, I understand that we have implicit conversions (without data loss), explicit conversions (necessary if there is a risk of data loss), the Convert class ("envelope wrapper", I think), and also (for example, double x = Double.Parse("2"); ), but I did not find anything similar to the as operator above.

So my question is this: does the infrastructure provide some method / operator / method for doing something in this direction:

  if (!Convert.CanConvert(someValue, someValueType)) { // Beware! Data loss can occur } else { // No data loss here } 

If not, can anyone out there offer a solid approach to building one such CanConvert method?

Thank you so much!

EDIT (1): The user problem / problem is as follows: Given something passed by the consumer of the code (my other self, but it doesn't matter), (1) Check that something is a number (simple enough) and (2) Put something in the "smallest" numeric type where it fits without causing data loss.

Some background: the nature of what I'm trying to do is more mathematical than technical: I'm trying to figure out if I can / how I can put existing number types into some kind of algebraic hierarchy of the form Monoid => Group => Ring => Field (or its simplified version). While working on this, and not very confidently, how "one led to the other," and it seemed to me that I had to deal with type conversions ...

+6
math algebra
source share
6 answers

What about the TryParse method for different types of values?

 int x; if (int.TryParse(someType.ToString(), out x)) return x; 
+3
source share

Henk is heavily dependent on money. I would like to add something to his answer if I:

Value type conversion in the .NET Framework works using the IConvertible interface. The Convert class uses this for almost all of its methods. This is very different from the implicit / explicit conversion operators in C #, which are just another form of syntactic sugar.

If you write this:

 public struct Duck { public static implicit operator Goose(Duck d) { ... } } 

The .NET Framework itself has no idea that this exists. It is emitted as op_implicit , and it is up to a compiled language to figure out how to use it. Not every MSIL language really supports them. So this code works:

 Goose g1 = duck; 

There is no in this code:

 Goose g1 = (Goose)Convert.ChangeType(duck, typeof(Goose)); 

To implement the CanConvert method, which knows about implicit / explicit conversion operations, you really need to use Reflection to test individual op_ methods, and I would have to recommend against this - In practice, I can use little.

+2
source share

The as operator is based on inheritance, and value types are not inherited. You could probably write CanConvert() , but it should work with Boxed valuetypes, and you usually want to avoid boxing.

So, it is possible: Yes, preferably: No.

Perhaps you can add a Use-Case script in which you want to use it, and then we can recommend alternatives.

Re: Edit (1)

I hope you know that the system of numerical types is basically historical baggage and does not follow very logical rules. For example, there is no such thing as evaluating short ; they are always converted to int before doing anything.

But perhaps you can define this behavior in terms of the Ring and the Field, that Algebra was "a long time" for me.

+1
source share

Take a look at Convert.ChangeType . You could grab it to fit your goals, although it would be slow due to throw elimination and duplication of conversion.

+1
source share

the keyword "how" is basically a safe downcast. Since all types of values ​​are sealed, they cannot be inherited.

So your code will look like this:

 if (firstObject is MyValueType) { MyValueType obj = (MyValueType) firstObject; } else { } 
+1
source share

I think you misunderstand the essence of the operator. The as operator is roughly equivalent to the following code:

 if (firstObject is SomeType) return (SomeType)firstObject; else return null; 

Since this is more of an inheritance check. (For example, List implements IList)

Value types do not support inheritance and not without reason. Double and Int64 both store number 1 in completely different ways.

Basically, you want to use a method that will determine for you whether the number conversion is hassle-free or not. Well, I agree with "Why?". Although quite a few formats are supported in the CLR, conversion rules are usually quite simple. For example, Int32 β†’ Double is lossless, and any conversion from "smaller" to "larger" is lossless, for example SByte β†’ Int64.

Another question: what will the false mean in your example? I would say very little, for example:

 Convert.CanConvert(123456789.12345F, typeof(Byte)) 

What use is a false result? You mean that this applies to cases like Int32 -> Single, where some data will be lost, but in this case a ton of data is lost, since the "nearest" byte representation is 255.

It is precisely because of these two problems that there is no such method.

+1
source share

All Articles