As far as I know, there are at least 3 ways to convert data types in .NET:
using System.ComponentModel.TypeConverter
var conv = System.ComponentModel.TypeDescriptor.GetConverter(typeof(int));
var i1 = (int)conv.ConvertFrom("123");
using System.Convert.ChangeType():
var i2 = (int) Convert.ChangeType("123", typeof (int));
using the Parse/TryParse methods of the destination type:
var i3 = int.Parse("123"); // or TryParse
Are there any guidelines or rules-of-thumb when to use which method to convert between the .NET base data types (especially from string to some other data type)?
I'm going to post here 6 years late, because I think this is a good question and I am not satisfied with the existing answers.
The static Parse/TryParse methods can be used only when you want to convert from string to the type that has those methods. (use TryParse when you expect that the conversion may fail).
The point of System.Convert is, as its documentation says, to convert from a base data type to another base data type. Note that with Convert you also have methods that take an Object and figure out by themselves how to convert it.
As to System.ComponentModel.TypeConverter, as the "typeconverter" stack overflow tag's documentation, they are used primarily to convert to and from string, when you want to provide a text representation of a class instance for use by designer serialization or for display in property grids
Convert
Convert class uses the IConvertible methods implemented in the target type.
Unfortunately, implementing IConvertible means writing lots of boilerplate code and Convert.ChangeType causes boxing if the target type is a struct.
TypeConverterAttribute
TypeDescriptor.GetConverter uses the TypeConverterAttribute and IMHO offers both a better API to convert a type and a more elegant way to make a type convertible. But it suffers the same performance issues with the Convert class, caused by the methods not being generic.
Parse/TryParse
Using T.Parse/T.TryParse methods is the de facto way of creating an object from a string since it doesn't involve unnecessary boxing. They also usually have overloads that provide greater control of how to parse the string.
TryParse methods allow you to handle cases where the string you want to parse is obtained from user input or another mean that doesn't guarantee a properly formatted string, without throwing exceptions.
So you should call the type's Parse/TryParse methods when you can and fallback to the other ways only when you don't know the target type in the compile time, i.e. when you only have a Type object that represents your target type.
You can also have look at my little library called ValueString that finds the most suitable parsing method of a type and uses it to parse the string.
According to my personal preference and coding standards I choose between the following:
Convert. I use this when I am absolutely sure that the values will be what I expect.
int i = Convert.ToInt32("123");
TryParse. I use this when I am handling user input. This also has the benefit to be able to use localized formatting when parsing.
int i = 0;
bool parsed = Int32.TryParse("123", out i);
There is also the possibility to use TryParseExact, where a certain pattern can be parsed. It can be useful in certain cases.
Just found out a case that TypeConvert.ConvertFrom(object) throws exception.
If you want to convert an Integer 0/1 to a Boolean. You will get exception using TypeConvert.ConvertFrom(1) or (0). In this case, Convert.ChangeType(1, System.Boolean) works.
As a general rule of thumb, you should be avoiding the Convert class altogether. There are reasons to use it (e.g, you do not know the source type), but if you already know your source type is a string then Parse (or, more correctly, TryParse) is always the right method to use.
As for type converters, they are more often than not used when a framework (such as WPF) uses reflection to determine the right sort of type converter.
You forgot another way of converting, that is the direct cast. Take this code for example
object i = 1;
int myInt = (int)i;
This is a bit of a contrived example, but I already know that i is an int, its just that its boxed into an object. In this case I do not need to convert i, I just need to directly cast it to the type which I know it already is.
I pretty much always use the int/double/etc.Parse() methods, when I'm certain it's a number. In any case of doubt, I us the .TryParse() methods, as an all-in-one solution including parsing and checking. I have this feeling that checking and parsing combined is slightly more performant than doing them separately.
TypeConverter is probably only useful when you don't really know the types at compile time.
Another late answer. I have an application where I was using some code that looks like this:
var finalValue = Convert.ChangeType(sourceValue, targetProperty.PropertyType);
sourceValue would be a string representation of what I wanted which normally would be a primitive under a wrapper class. This way would work with regular data types. Even with entire classes. However, one day I stupidly decided to change the datatype of a property that was a double to a nullable one double? guess what? boom!
invalid cast from string to nullable double
This is the perfect scenario where you should use the TypeConverter class as follows:
void Main()
{
var ss = new[] {"2.01", "3.99", ""};
var conv = TypeDescriptor.GetConverter(typeof(A).GetProperties().First().PropertyType);
Console.WriteLine(string.Join(",", ss.Select(s => conv.ConvertFrom(s))));
}
class A {
public double? b {get; set;}
}
//2.01,3.99,
Related
I am using reflection and I want to do conversion checking for exception handling.
I need to check if string can convert to unknown type in my project.
I used :
TypeConverter t = TypeDescriptor.GetConverter(typeof(string));
Console.WriteLine(t.CanConvertTo(typeof(int)));
but it returns false !
or even this one returns false again :
StringConverter stringConverter = new StringConverter();
Console.WriteLine(stringConverter.CanConvertTo(typeof(int)));
my quesion is that why StringConverter returns false for converting string to int ???
EDIT :
I use this code to convert string to unknown types : ( result is string )
resultCastedToTargetPropertyType = Convert.ChangeType(result,propertyInfo.PropertyType);
Oddities of the implementation of CanConvertFrom aside, in your context you wouldn't get much help by knowing that a certain conversion could be performed until you try it. A converter cannot give you a definitive answer based on the type alone, for the same reason that there is no single answer to the question "can a string be converted to integer": the answer is "it depends on the string" - i.e. string "123" can be converted to int, while strings "hello" and "1234567891011121314151617181920" cannot be converted to int.
In other words, the answer could be obtained only when you know the value being converted. In your case it means putting try/catch block around your call of Convert.ChangeType, and interpreting each of the four exceptions it could throw (reference).
A StringConverter only cares about string. What you would need is System.ComponentModel.Int32Converter. It is Int32Converter that cares about int. TypeDescriptor.GetConverter(typeof(int)) gives you that.
Essentially, a TypeConverter is usually used to format a target type to display, or to parse input back to that target type. There's nothing much involved in displaying or parsing a string to/from a string, so you will be unsurprised to hear that StringConverter does very little! Here, the interesting type is int, and Int32Converter knows how to format an int for display, and parse an int from input.
The docs for StringConverter state:
This converter can only convert to a string. It works as a pass
through for other converters that want to convert an object to a
string.
Int32Converter, on the other hand, states:
This converter can only convert a 32-bit signed integer object to and
from a string. The Int32 value type represents signed integers with
values ranging from negative 2,147,483,648 through positive
2,147,483,647.
As such Int32Converter is likely what you want to use, rather than StringConverter.
Alternatively, consider writing a Convert.TryChangeType extension method, with a try catch block in it - this will avoid you having to worry about the individual converters. In effect you will 'try it and see'. This is especially important when doing conversions where you aren't sure whether they will work until runtime (e.g "abc" to int).
I have a function that casts a double on string values.
string variable = "5.00";
double varDouble = (double)variable;
A code change was checked in and the project builds with the error: System.InvalidCastException: Specified cast is not valid.
However, after doing the following...
string variable = "5.00";
double varDouble = Convert.ToDouble(variable);
...the project builds without any errors.
What is the difference between casting and using the Convert.To() method? Why does casting throw an Exception and using the Convert.To() does not?
Even if you may see them somehow as equivalent they're completely different in purpose. Let's first try to define what a cast is:
Casting is the action of changing an entity of one data type into another.
It's a little bit generic and it's somehow equivalent to a conversion because a cast often has the same syntax of a conversion so the question should be when a cast (implicit or explicit) is allowed by the language and when do you have to use a (more) explicit conversion?
Let me first draw a simple line between them. Formally (even if equivalent for language syntax) a cast will change the type while a conversion will/may change the value (eventually together with the type). Also a cast is reversible while a conversion may not be.
This topic is pretty vast so let's try to narrow it a little bit by excluding custom cast operators from the game.
Implicit casts
In C# a cast is implicit when you won't lose any information (please note that this check is performed with types and not with their actual values).
Primitive types
For example:
int tinyInteger = 10;
long bigInteger = tinyInteger;
float tinyReal = 10.0f;
double bigReal = tinyReal;
These casts are implicit because during the conversion you won't lose any information (you just make the type wider). Vice versa implicit cast isn't allowed because, regardless of their actual values (because they can be checked only at run-time), during the conversion you may lose some information. For example this code won't compile because a double may contain (and actually it does) a value not representable with a float:
// won't compile!
double bigReal = Double.MaxValue;
float tinyReal = bigReal;
Objects
In case of an object (a pointer to) the cast is always implicit when the compiler can be sure that the source type is a derived class (or it implements) the type of the target class, for example:
string text = "123";
IFormattable formattable = text;
NotSupportedException derivedException = new NotSupportedException();
Exception baseException = derivedException;
In this case the compiler knows that string implements IFormattable and that NotSupportedException is (derives from) Exception so the cast is implicit. No information is lost because objects don't change their types (this is different with structs and primitive types because with a cast you create a new object of another type), what changes is your view of them.
Explicit casts
A cast is explicit when the conversion isn't done implicitly by the compiler and then you must use the cast operator. Usually it means that:
You may lose information or data so you have to be aware of it.
The conversion may fail (because you can't convert one type to the other) so, again, you must be aware of what you're doing.
Primitive types
An explicit cast is required for primitive types when during the conversion you may lose some data, for example:
double precise = Math.Cos(Math.PI * 1.23456) / Math.Sin(1.23456);
float coarse = (float)precise;
float epsilon = (float)Double.Epsilon;
In both examples, even if the values fall within the float range, you'll lose information (in this case precision) so the conversion must be explicit. Now try this:
float max = (float)Double.MaxValue;
This conversion will fail so, again, it must be explicit so you're aware of it and you may do a check (in the example the value is constant but it may come from some run-time computations or I/O). Back to your example:
// won't compile!
string text = "123";
double value = (double)text;
This won't compile because the compiler can't convert text to numbers. Text may contain any characters, not numbers only and this is too much, in C#, even for an explicit cast (but it may be allowed in another language).
Objects
Conversions from pointers (to objects) may fail if the types are unrelated, for example this code won't compile (because the compiler knows there is no possible conversion):
// won't compile!
string text = (string)AppDomain.Current;
Exception exception = (Exception)"abc";
This code will compile but it may fail at run-time (it depends on the effective type of casted objects) with an InvalidCastException:
object obj = GetNextObjectFromInput();
string text = (string)obj;
obj = GetNextObjectFromInput();
Exception exception = (Exception)obj;
Conversions
So, finally, if casts are conversions then why do we need classes like Convert? Ignoring the subtle differences that come from Convert implementation and IConvertible implementations actually because in C# with a cast you say to the compiler:
trust me, this type is that type even if you can't know it now, let me do it and you'll see.
-or-
don't worry, I don't care if something will be lost in this conversion.
For anything else a more explicit operation is needed (think about implications of easy casts, that's why C++ introduced long, verbose and explicit syntax for them). This may involve a complex operation (for string -> double conversion a parsing will be needed). A conversion to string, for example, is always possible (via ToString() method) but it may mean something different from what you expect so it must be more explicit than a cast (more you write, more you think about what you're doing).
This conversion can be done inside the object (using known IL instructions for that), using custom conversion operators (defined in the class to cast) or more complex mechanisms (TypeConverters or class methods, for example). You're not aware of what will happen to do that but you're aware it may fail (that's why IMO when a more controlled conversion is possible you should use it). In your case the conversion simply will parse the string to produce a double:
double value = Double.Parse(aStringVariable);
Of course this may fail so if you do it you should always catch the exception it may throw (FormatException). It's out of topic here but when a TryParse is available then you should use it (because semantically you say it may not be a number and it's even faster...to fail).
Conversions in .NET can come from a lot of places, TypeConverter, implicit/explicit casts with user defined conversion operators, implementation of IConvertible and parsing methods (did I forget something?). Take a look on MSDN for more details about them.
To finish this long answer just few words about user defined conversion operators. It's just sugar to let the programmer use a cast to convert one type to another. It's a method inside a class (the one that will be casted) that says "hey, if he/she wants to convert this type to that type then I can do it". For example:
float? maybe = 10; // Equals to Nullable<float> maybe = 10;
float sure1 = (float)maybe; // With cast
float sure2 = maybe.Value; // Without cast
In this case it's explicit because it may fail but this is let to the implementation (even if there are guidelines about this). Imagine you write a custom string class like this:
EasyString text = "123"; // Implicit from string
double value = (string)text; // Explicit to double
In your implementation you may decide to "make programmer's life easier" and to expose this conversion via a cast (remember it's just a shortcut to write less). Some language may even allow this:
double value = "123";
Allowing implicit conversion to any type (check will be done at run-time). With proper options this can be done, for example, in VB.NET. It's just a different philosophy.
What can I do with them?
So the final question is when you should use one or another. Let's see when you can use an explicit cast:
Conversions between base types.
Conversions from object to any other type (this may include unboxing too).
Conversions from a derived class to a base class (or to an implemented interface).
Conversions from one type to another via custom conversion operators.
Only the first conversion can be done with Convert so for the others you have no choice and you need to use an explicit cast.
Let's see now when you can use Convert:
Conversions from any base type to another base type (with some limitations, see MSDN).
Conversions from any type that implements IConvertible to any other (supported) type.
Conversions from/to a byte array to/from a string.
Conclusions
IMO Convert should be used each time you know a conversion may fail (because of the format, because of the range or because it may be unsupported), even if the same conversion can be done with a cast (unless something else is available). It makes clear to who will read your code what's your intent and that it may fail (simplifying debug).
For everything else you need to use a cast, no choice, but if another better method is available then I suggest you use it. In your example a conversion from string to double is something that (especially if text comes from user) very often will fail so you should make it as much explicit as possible (moreover you get more control over it), for example using a TryParse method.
Edit: what's the difference between them?
According to updated question and keeping what I wrote before (about when you can use a cast compared to when you can/have to use Convert) then last point to clarify is if there are difference between them (moreover Convert uses IConvertible and IFormattable interfaces so it can perform operations not allowed with casts).
Short answer is yes, they behave differently. I see the Convert class like a helper methods class so often it provides some benefit or slightly different behaviors. For example:
double real = 1.6;
int castedInteger = (int)real; // 1
int convertedInteger = Convert.ToInt32(real); // 2
Pretty different, right? The cast truncates (it's what we all expect) but Convert performs a rounding to nearest integer (and this may not be expected if you're not aware of it). Each conversion method introduces differences so a general rule can't be applied and they must be seen case by case...19 base types to convert to every other type...list can be pretty long, much better to consult MSDN case by case!
Casting is a way of telling the compiler, "I know that you think that this variable is a Bar, but I happen to know more than you; the object is actually a Foo, so let me treat it as if it were a Foo from now on." Then, at runtime, if the actual object turned out to really be a Foo then your code works, if it turns out that the object was not a Foo at all, then you get an exception. (Specifically an System.InvalidCastException.)
Converting on the other hand is a way of saying, "If you give me an object of type Bar I can create a brand new Foo object that represents what is in that Bar object. I won't change the original object, it won't treat the original object differently, it will create something new that is just based on some other value. As to how it will do that, it could be anything. In the case of Convert.ToDouble it will end up calling Double.Parse which has all sorts of complex logic for determining what types of strings represent what numeric values. You could write your own conversion method that mapped strings to doubles differently (perhaps to support some entirely different convention for displaying numbers, such as roman numerals or whatever). A conversion could do anything, but the idea is that you're not really asking the compiler to do anything for you; you are the one writing the code to determine how to create the new object because the compiler, without your help, has no way of knowing how to map (as an example) a string to a double.
So, when do you convert, and when do you cast? In both cases we have some variable of a type, let's say A, and we want to have a variable of type B. If our A object really, actually, under the hood, is a B, then we cast. If it's not really a B, then we need to Convert it, and define how the program is supposed to get a B from an A.
From MSDN:
Explicit conversions (casts): Explicit conversions require a cast operator. Casting is required when information might be lost in the conversion, or when the conversion might not succeed for other reasons. Typical examples include numeric conversion to a type that has less precision or a smaller range, and conversion of a base-class instance to a derived class.
Consider the following example:
double a = 2548.3;
int b;
b = (int)a; //2548 --> information (.3) lost in the conversion
And also:
A cast is a way of explicitly informing the compiler that you intend to make the conversion and that you are aware that data loss might occur.
You could use System.Convert class when you want to convert between non-compatible types. The main difference between casting and convert is compile and run-time. The type conversion exceptions are appeared at run-time , i.e a type cast that fails at run-time will cause an InvalidCastException to be thrown.
Conclusion: In casting you are telling to the compiler that a is really type b and if so the project builds without any errors like this example:
double s = 2;
int a = (int) s;
But in conversion you're saying to the compiler there is a way to create a new object from a of type b, please do it and project builds without any errors but as I said if type cast fails at run-time, it will cause an InvalidCastException to be thrown.
For example the code below is never compile because compiler detect that cannot cast expression of type DateTime to type int:
DateTime s = DateTime.Now;
int a = (int)(s);
But this one is compiled successfully:
DateTime s = DateTime.Now;
int a = Convert.ToInt32(s);
But at run-time you will get InvalidCastException which says:
Invalid cast from 'DateTime' to 'Int32'.
In your example you are attempting to cast a string to a double (non integral type).
An explicit conversion is required for it to work.
And i must point that you could have used Convert.ToDouble instead of Convert.ToInt64 as you can lose the fractional parts of the double value when you convert to an int.
if your variable has the value "5.25" varDouble would have been 5.00 (loss of 0.25 because of the Conversion to Int64)
To answer your question about casting vs converting.
Your cast (an explicit cast) doesn't meet the requirements for an explicit cast. the value you are trying to cast with the cast operator is invalid (i.e non integral).
Visit this MSDN Page for the rules of casting / conversions
The Convert.Double method actually just internally calls the Double.Parse(string) method.
Neither the String type nor the Double type define an explicit/implicit conversion between the two types, so casting will always fail.
The Double.Parse method will look at each character in the string and build a numeric value based on the values of the characters in the string. If any of the characters are invalid, the Parse method fails (causing the Convert.Double method to fail as well).
Casting does not involve any conversion, i.e. the internal representation of a value is not changed. Example:
object o = "Hello"; // o is typed as object and contains a string.
string s = (string)o; // This works only if o really contains a string or null.
You can convert a double to string like this
double d = 5;
string s = d.ToString(); // -> "5"
// Or by specifying a format
string formatted = d.ToString("N2"); // -> "5.00"
You can convert a string to a double in several ways (here just two of them):
string s = "5";
double d = Double.Parse(s); // Throws an exception if s does not contain a valid number
Or the safe way
string s = "5";
double d;
if (Double.TryParse(s, out d)) {
Console.WriteLine("OK. Result = {0}", d);
} else {
Console.WriteLine("oops!");
}
double varDouble = (double)variable assumes that variable is already a double. If variable isn't a double (it's a string) then this will fail.
double varDouble = Convert.ToDouble(variable) does like it says - it converts. If it can parse or otherwise extract a double from variable then it will.
I second using Double.Parse or Double.TryParse because it more clearly indicates what's supposed to be happening. You're starting with a string and expecting it to be convertible to a double. If there's any doubt, use TryParse.
If variable is a method argument, change the type to double. Make the caller responsible for providing the correct type. That way the compiler does the work for you.
string variable = "5.00";
double varDouble = (double)variable;
Above conversion is simply not allowed by language. Here is a list of explicit casts for numerical types: http://msdn.microsoft.com/en-us/library/yht2cx7b.aspx As you can see, even not every numerical type could be converted to another numerical type
Some more info about casting here
And how does this differ to Convert.ToDouble()?
When you cast a type, data structure is not changed. Well, in case of numerical values conversion it you may loose few bits or get few additional 0 bits. But you are still working with a number. You are just changing an amount of memory taken by that number. That is safe enough for compiler do everything needed.
But when you are trying to cast string to a number, you can't do that because it is not enough to change amount of memory taken by variable. For instance, 5.00 as a string is a sequence of "numbers":53(5) 46(.) 48(0) 48(0) - that is for ASCII, but string will contain something similar. If compiler will just take first N (4 for double? not sure) bytes from a string - that piece will contain completely different double number.
At the same time Convert.ToDouble() run special algorithm which will take each symbol of a string, figure out digit which it represents and make a double number for you, if string represents a number.
Languages like PHP will, roughly speaking, call Convert.ToDouble for you in background. But C#, like a statically typed language, will not do that for you. This allows you to be sure that any operation is type safe and you will not get something unexpected doing something like:
double d = (double)"zzzz"
Casting a string to a double like that is not allowed C# which is why you get an Exception, you need to have the string converted (MSDN doc that shows acceptable conversion paths). This is simply because a string isn't necessarily going to contain numeric data, but the various numeric types will (barring null values). A Convert will run a method that will check the string to see if it can be turned into a numeric value. If it can, then it will return that value. If it can't, it'll throw an exception.
To convert it, you have several options. You used the Convert method in your question, there's Parse which is largely similar to Convert, but you should also look at TryParse which would allow you to do:
string variable = "5.00";
double varDouble;
if (Double.TryParse(variable, out varDouble)) {
//Code that runs if the conversion succeeded.
} else {
//Code that runs if the conversion failed.
}
This avoids the possible exception should you try to Convert or Parse a non-numerical string.
The most important difference is that if type casting is used and the conversion fails
(say we are converting a very big float value to int ) no exception will be thrown and the minimum value an int can hold will be shown.
But in case of using Convert , an exception will be thrown for such scenarios.
I have to cast an object to an object, where i just have the typename as a string.
For example:
I have the type-string System.DateTime and the string 2012-09-17T10:19:23.5369243+02:00. Now I want to have an object of DateTime with the value of the string.
Is this possible?
The answer to your question can be found in all the other answers, waiting to be pieced together. :)
Get the Type from your Type String, like akhisp said:
Type dateTimeType = Type.GetType("System.DateTime");
Now, use a type converter to change the string to the DateTime:
object date = Convert.ChangeType("2012-09-17T10:19:23.5369243+02:00", dateTimeType);
Usually this kind of conversion is not exposed through a cast. There are many reasons for this (and it could be a nice topic for an another question).
Sometimes the string representation of an object is pretty "standard" for that object. For example a color may always be serialized as a comma separated RGB triplet.
Things become harder when the type you need to parse introduces locale-dependent representations: a date, for example. In this case framework designers decided to do not introduce an interface like IParseable and to do this kind of stuff using a 3rd object:TypeConverters, TypeDescriptors and conversion classes. It makes your code more complicated but it allows to manage very complex conversions delegating the work to another class, take a look to:
System.ComponentModel.TypeConverter on MSDN.
System.ComponentModel.TypeDescriptor on MSDN.
Understanding the TypeDescriptor: A Metadata Engine for Designtime Code
For primitive types you may not even need to use them: you can rely on IConvertible interface and System.Convert class.
You can't do it with a cast (thanks God, in my opinion) but you can write a generic Parse method that accepts a string and returns the type you need, something like:
T Parse<T>(string value)
For what I remember there is a nice open source type conversion library (Universal Type Converter). It manages a lot of conversions using everything it may find to convert a type to another (imagine, for example, how many different string representations you may use for a bool value). Even if you won't use it directly you should read the article to understand how this things works (and to take a look to source code to see how corner cases have been handled).
What I would do is use the Type.GetType(String) method to get the Type of the object.
Then I would do a call to Activator.CreateInstance(Type Object[]) to construct an instance of that object, assuming you know that there is a constructor that takes in a string.
I've read a few related questions regarding this topic however none of them are making sense to me. As I understand it, in some cases you can use cast and parse interchangeably and achieve the same result.
Are there some general guidelines that can help me decide when to choose one approach over the other?
You generally use Parse() on a string whose value represents a valid value of the type to which you are converting.
Casting, on the other hand, is better used when you have an object of a derived type but stored in a base variable, and need to use it as its more specific type.
That is, if you have "1234" you can Parse() that into an int. But if you have
object variable = 1234;
You should cast it to get it back as an int.
Casting is more of a conversion of an object from a similar type. A good example is float to integer, or double to decimal. Parsing is just that; parsing. The definition or use of parsing is a bit more broad. You could write a Parse method in your own object similar to that of int.Parse or int.TryParse to convert a string to your object type. Parsing could also refer to things such as string manipulation to gather the data you need from any given string. "Parsing" does not necessarily relate to "Casting".
Another good example of casting is when using inheritance or interfaces.
public interface ICar {
// ...
}
public class Corvette : ICar {
// ...
}
public void Foo() {
Corvette mycar = new Corvette();
// Now do a cast
ICar = (ICar)mycar;
}
Have a look here, at Mark Gravell's comprehensive answer (will answer you about converting too..).
Casting : is conversion of an object from a similar datatype; like from int to double or from decimal to int. Casting does not create a new object, It will only assign a reference of one datatype to reference of another datatype, only if its assignable.
Parsing : Parsing, on the other side, is converting from one data type to another, like from string to int for example. This Creates a new Object, and returns reference to it.
In a nutshell, Casting will not create a new object, but deal with the same object reference, whereas parsing create a new object, and doesn't touch the old object in any way.
(OK, I'll expose the depths of my ignorance here, please be gentle)
Background
I've got a method which looks (a bit) like this:
public void AddLink(Enum enumVal)
{
string identifier = m_EnumInterpreter(enumVal);
AddLink(identifier);
}
The EnumInterpreter is a Func<Enum, string> that is passed in when the parent class is created.
I'm using Enum because at this level it is 'none of my business'- I don't care which specific enum it is. The calling code just uses a (generated) enum to avoid magic strings.
Question
If the EnumInterpreter sends back an empty string, I'd like to throw an exception with the actual value of enumVal. I thought I would just be able to cast to int, but it the compiler won't have it. What am I doing wrong? (Please don't say 'everything').
System.Enum cannot be directly cast to Integer, but it does explicitly implement IConvertible, meaning you can use the following:
public void AddLink(Enum enumVal)
{
string identifier = m_EnumInterpreter(Convert.ToInt32(enumVal));
AddLink(identifier);
}
Keep in mind that if your Enum is actually using something other than an Integer (such as a float), you'll lose the non-integer data on conversion. Or obviously replace the Convert call with whatever you are converting from (if it's known)
No, you aren't able to cast it to an int because System.Enum is not an enum, it's just the base class for enums.
EDIT:
You can get the value as follows, but it is ugly:
int intVar = (int)enuYourEnum.GetType().GetField("value__").GetValue(objYourEnum);
try this..
m_EnumInterpreter((int) (object) enumVal);
Various things here:
1) the answer of Ryan looks ok, but... I would rather pass the Enum down to the enum interpreter, so that you can do the whole Convert.To... there. If you know that you are using ONLY integer based enums, the Convert.ToInt32() is just fine. Otherwise you may want to add by using either reflection or try/catch other conversions.
2) You may also consider using members of the Enum class, like .GetName(), .GetValue(), etc. since they deal directly with the defined names and values independent of the enum type.
3) technically I would not throw the exception outside the enum interpreter. If that condition is generally true, throw the exception from inside the enum interpreter, so that all uses of the class will benefit of the validation. Or you might end up duplicating code.
4) you seem to have an C++/MFC background judging from your variable naming. You might want to get into C# style naming conventions, it will ease your life when using/reading other peoples code and libraries. Check out MS's StyleCop for a good addin to help with naming.
I don't know whether to include this in my question, or as an answer. The problem is that it isn't THE answer, but it is the answer that works for me.
What I discovered, by chance while trying something else, is that if I just wodge it onto the end of a string, I get what I want:
throw new Exception("EnumInterpreter returns empty string for enumVal=" + enumVal);
//EnumInterpreter returns empty string for enumVal=3720116125
I actually simplified to int in my question, the real data type is uint (in this particular instance). Fortunately, given that I only actually wanted the string, I don't have to worry about that.
I'm not sure which of the three other answers is 'right', so vote away...
For me it was enough to cast to object first, since it's just a compilation error.
public static int AsInt(this Enum #this)
{
return (int)(object)#this;
}
I understand that this is probably not the solution to your exact problem, but I just want to post how I solved this for a particular API I was using.
int result = (int) (ActualEnumType) MethodThatReturnsSystemEnumType( arg1, arg2 );
Hopefully that will be of help to someone. Double cast FTW.
Why not parse the enum to a string and return the actual enum value?
public enum MyEnum { Flower = 1, Tree = 2, Animal = 3 };
string name = MyEnum.Flower.ToString(); // returns "Flower"
I think .ToString() is deprecated and I'm not sure about the new way to do it. I would've thought the actual enum representation would be more useful than the int?