Difference between .ToString and "as string" in C# - c#

What is the difference between using the two following statements? It appears to me that the first "as string" is a type cast, while the second ToString is an actual call to a method that converts the input to a string? Just looking for some insight if any.
Page.Theme = Session["SessionTheme"] as string;
Page.Theme = Session["SessionTheme"].ToString();

If Session["SessionTheme"] is not a string, as string will return null.
.ToString() will try to convert any other type to string by calling the object's ToString() method. For most built-in types this will return the object converted to a string, but for custom types without a specific .ToString() method, it will return the name of the type of the object.
object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;
string s = o1 as string; // returns "somestring"
string s = o1.ToString(); // returns "somestring"
string s = o2 as string; // returns null
string s = o2.ToString(); // returns "1"
string s = o3 as string; // returns null
string s = o3.ToString(); // returns "System.Object"
string s = o4 as string; // returns null
string s = o4.ToString(); // throws NullReferenceException
Another important thing to keep in mind is that if the object is null, calling .ToString() will throw an exception, but as string will simply return null.

The as keyword will basically check whether the object is an instance of the type, using MSIL opcode isinst under the hood. If it is, it returns the reference to the object, else a null reference.
It does not, as many say, attempt to perform a cast as such - which implies some kind of exception handling. Not so.
ToString(), simply calls the object's ToString() method, either a custom one implemented by the class (which for most in-built types performs a conversion to string) - or if none provided, the base class object's one, returning type info.

I'm extending Philippe Leybaert's accepted answer a bit because while I have found resources comparing three of these, I've never found an explanation that compares all four.
(string)obj
obj as string
obj.ToString()
Convert.ToString(obj)
object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;
Console.WriteLine((string)o1); // returns "somestring"
Console.WriteLine(o1 as string); // returns "somestring"
Console.WriteLine(o1.ToString()); // returns "somestring"
Console.WriteLine(Convert.ToString(o1)); // returns "somestring"
Console.WriteLine((string)o2); // throws System.InvalidCastException
Console.WriteLine(o2 as string); // returns null
Console.WriteLine(o2.ToString()); // returns "1"
Console.WriteLine(Convert.ToString(o2)); // returns "1"
Console.WriteLine((string)o3); // throws System.InvalidCastException
Console.WriteLine(o3 as string); // returns null
Console.WriteLine(o3.ToString()); // returns "System.Object"
Console.WriteLine(Convert.ToString(o3)); // returns "System.Object"
Console.WriteLine((string)o4); // returns null
Console.WriteLine(o4 as string); // returns null
Console.WriteLine(o4.ToString()); // throws System.NullReferenceException
Console.WriteLine(Convert.ToString(o4)); // returns string.Empty
From these results we can see that (string)obj and obj as string behave the same way as each other when obj is a string or null; otherwise (string)obj will throw an invalid cast exception and obj as string will just return null. obj.ToString()
and Convert.ToString(obj) also behave the same way as each other except when obj is null, in which case obj.ToString() will throw a null reference exception and Convert.ToString(obj) will return an empty string.
So here are my recommendations:
(string)obj works best if you want to throw exceptions for types that can't be assigned to a string variable (which includes null)
obj as string works best if you don't want to throw any exceptions and also don't want string representations of non-strings
obj.ToString() works best if you want to throw exceptions for null
Convert.ToString(obj) works best if you don't want to throw any exceptions and want string representations of non-strings
EDIT: I've discovered that Convert.ToString() actually treats null differently depending on the overload, so it actually matters that the variable was declared as an object in this example. If you call Convert.ToString() on a string variable that's null then it will return null instead of string.Empty.

Page.Theme = Session["SessionTheme"] as string;
tries to cast to a string
whereas
Page.Theme = Session["SessionTheme"].ToString();
calls the ToString() method, which can be anything really. This method doesn't cast, it should return a string representation of this object.

To confuse the matter further, C# 6.0 has introduced the null-conditional operator. So now this can also be written as:
Page.Theme = Session["SessionTheme"]?.ToString();
Which will return either null or the result from ToString() without throwing an exception.

First of all "any-object as string" and "any-object.ToString()" are completely different things in terms of their respective context.
string str = any-object as string;
1) This will cast any-object as string type and if any-object is not castable to string then this statement will return null without throwing any exception.
2) This is a compiler-service.
3) This works pretty much well for any other type other than string, ex: you can do it as any-object as Employee, where Employee is a class defined in your library.
string str = any-object.ToString();
1) This will call ToString() of any-object from type-defination. Since System.Object defines ToString() method any class in .Net framework has ToString() method available for over-riding. The programmer will over-ride the ToString() in any-object class or struct defination and will write the code that return suitable string representation of any-object according to responsibility and role played by any-object.
2) Like you can define a class Employee and over-ride ToString() method which may return Employee object's string representation as "FIRSTNAME - LASTNAME, EMP-CDOE" .
Note that the programmer has control over ToString() in this case and it has got nothing to do with casting or type-conversion.

The as string check is the object is a string. If it isn't a null it returned.
The call to ToString() will indeed call the ToString() method on the object.

The first one returns the class as a string if the class is a string or derived from a string (returns null if unsuccessful).
The second invokes the ToString() method on the class.

Actually the best way of writing the code above is to do the following:
if (Session["SessionTheme"] != null)
{
Page.Theme = Session["SessionTheme"].ToString();
}
That way you're almost certain that it won't cast a NullReferenceException.

Related

What is the difference between these two casting methods? [duplicate]

Consider the following code:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
What is the difference between the three types of casting (okay, the 3rd one is not a casting, but you get the intent). Which one should be preferred?
string s = (string)o; // 1
Throws InvalidCastException if o is not a string. Otherwise, assigns o to s, even if o is null.
string s = o as string; // 2
Assigns null to s if o is not a string or if o is null. For this reason, you cannot use it with value types (the operator could never return null in that case). Otherwise, assigns o to s.
string s = o.ToString(); // 3
Causes a NullReferenceException if o is null. Assigns whatever o.ToString() returns to s, no matter what type o is.
Use 1 for most conversions - it's simple and straightforward. I tend to almost never use 2 since if something is not the right type, I usually expect an exception to occur. I have only seen a need for this return-null type of functionality with badly designed libraries which use error codes (e.g. return null = error, instead of using exceptions).
3 is not a cast and is just a method invocation. Use it for when you need the string representation of a non-string object.
string s = (string)o; Use when something should
definitely be the other thing.
string s = o as string; Use when something might be the other
thing.
string s = o.ToString(); Use when you don't care what
it is but you just want to use the
available string representation.
It really depends on whether you know if o is a string and what you want to do with it. If your comment means that o really really is a string, I'd prefer the straight (string)o cast - it's unlikely to fail.
The biggest advantage of using the straight cast is that when it fails, you get an InvalidCastException, which tells you pretty much what went wrong.
With the as operator, if o isn't a string, s is set to null, which is handy if you're unsure and want to test s:
string s = o as string;
if ( s == null )
{
// well that's not good!
gotoPlanB();
}
However, if you don't perform that test, you'll use s later and have a NullReferenceException thrown. These tend to be more common and a lot harder to track down once they happens out in the wild, as nearly every line dereferences a variable and may throw one. On the other hand, if you're trying to cast to a value type (any primitive, or structs such as DateTime), you have to use the straight cast - the as won't work.
In the special case of converting to a string, every object has a ToString, so your third method may be okay if o isn't null and you think the ToString method might do what you want.
'as' is based on 'is', which is a keyword that checks at runtime if the object is polimorphycally compatible (basically if a cast can be made) and returns null if the check fails.
These two are equivalent:
Using 'as':
string s = o as string;
Using 'is':
if(o is string)
s = o;
else
s = null;
On the contrary, the c-style cast is made also at runtime, but throws an exception if the cast cannot be made.
Just to add an important fact:
The 'as' keyword only works with reference types. You cannot do:
// I swear i is an int
int number = i as int;
In those cases you have to use casting.
If you already know what type it can cast to, use a C-style cast:
var o = (string) iKnowThisIsAString;
Note that only with a C-style cast can you perform explicit type coercion.
If you don't know whether it's the desired type and you're going to use it if it is, use as keyword:
var s = o as string;
if (s != null) return s.Replace("_","-");
//or for early return:
if (s==null) return;
Note that as will not call any type conversion operators. It will only be non-null if the object is not null and natively of the specified type.
Use ToString() to get a human-readable string representation of any object, even if it can't cast to string.
The as keyword is good in asp.net when you use the FindControl method.
Hyperlink link = this.FindControl("linkid") as Hyperlink;
if (link != null)
{
...
}
This means you can operate on the typed variable rather then having to then cast it from object like you would with a direct cast:
object linkObj = this.FindControl("linkid");
if (link != null)
{
Hyperlink link = (Hyperlink)linkObj;
}
It's not a huge thing, but it saves lines of code and variable assignment, plus it's more readable
According to experiments run on this page: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as
(this page is having some "illegal referrer" errors show up sometimes, so just refresh if it does)
Conclusion is, the "as" operator is normally faster than a cast. Sometimes by many times faster, sometimes just barely faster.
I peronsonally thing "as" is also more readable.
So, since it is both faster and "safer" (wont throw exception), and possibly easier to read, I recommend using "as" all the time.
2 is useful for casting to a derived type.
Suppose a is an Animal:
b = a as Badger;
c = a as Cow;
if (b != null)
b.EatSnails();
else if (c != null)
c.EatGrass();
will get a fed with a minimum of casts.
"(string)o" will result in an InvalidCastException as there's no direct cast.
"o as string" will result in s being a null reference, rather than an exception being thrown.
"o.ToString()" isn't a cast of any sort per-se, it's a method that's implemented by object, and thus in one way or another, by every class in .net that "does something" with the instance of the class it's called on and returns a string.
Don't forget that for converting to string, there's also Convert.ToString(someType instanceOfThatType) where someType is one of a set of types, essentially the frameworks base types.
It seems the two of them are conceptually different.
Direct Casting
Types don't have to be strictly related. It comes in all types of flavors.
Custom implicit/explicit casting: Usually a new object is created.
Value Type Implicit: Copy without losing information.
Value Type Explicit: Copy and information might be lost.
IS-A relationship: Change reference type, otherwise throws exception.
Same type: 'Casting is redundant'.
It feels like the object is going to be converted into something else.
AS operator
Types have a direct relationship. As in:
Reference Types: IS-A relationship Objects are always the same, just the reference changes.
Value Types: Copy boxing and nullable types.
It feels like the you are going to handle the object in a different way.
Samples and IL
class TypeA
{
public int value;
}
class TypeB
{
public int number;
public static explicit operator TypeB(TypeA v)
{
return new TypeB() { number = v.value };
}
}
class TypeC : TypeB { }
interface IFoo { }
class TypeD : TypeA, IFoo { }
void Run()
{
TypeA customTypeA = new TypeD() { value = 10 };
long longValue = long.MaxValue;
int intValue = int.MaxValue;
// Casting
TypeB typeB = (TypeB)customTypeA; // custom explicit casting -- IL: call class ConsoleApp1.Program/TypeB ConsoleApp1.Program/TypeB::op_Explicit(class ConsoleApp1.Program/TypeA)
IFoo foo = (IFoo)customTypeA; // is-a reference -- IL: castclass ConsoleApp1.Program/IFoo
int loseValue = (int)longValue; // explicit -- IL: conv.i4
long dontLose = intValue; // implict -- IL: conv.i8
// AS
int? wraps = intValue as int?; // nullable wrapper -- IL: call instance void valuetype [System.Runtime]System.Nullable`1<int32>::.ctor(!0)
object o1 = intValue as object; // box -- IL: box [System.Runtime]System.Int32
TypeD d1 = customTypeA as TypeD; // reference conversion -- IL: isinst ConsoleApp1.Program/TypeD
IFoo f1 = customTypeA as IFoo; // reference conversion -- IL: isinst ConsoleApp1.Program/IFoo
//TypeC d = customTypeA as TypeC; // wouldn't compile
}
All given answers are good, if i might add something:
To directly use string's methods and properties (e.g. ToLower) you can't write:
(string)o.ToLower(); // won't compile
you can only write:
((string)o).ToLower();
but you could write instead:
(o as string).ToLower();
The as option is more readable (at least to my opinion).
string s = o as string; // 2
Is prefered, as it avoids the performance penalty of double casting.
I would like to attract attention to the following specifics of the as operator:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as
Note that the as operator performs only reference conversions,
nullable conversions, and boxing conversions. The as operator can't
perform other conversions, such as user-defined conversions, which
should instead be performed by using cast expressions.
Use direct cast string s = (string) o; if in the logical context of your app string is the only valid type. With this approach, you will get InvalidCastException and implement the principle of Fail-fast. Your logic will be protected from passing the invalid type further or get NullReferenceException if used as operator.
If the logic expects several different types cast string s = o as string; and check it on null or use is operator.
New cool feature have appeared in C# 7.0 to simplify cast and check is a Pattern matching:
if(o is string s)
{
// Use string variable s
}
or
switch (o)
{
case int i:
// Use int variable i
break;
case string s:
// Use string variable s
break;
}
When trying to get the string representation of anything (of any type) that could potentially be null, I prefer the below line of code. It's compact, it invokes ToString(), and it correctly handles nulls. If o is null, s will contain String.Empty.
String s = String.Concat(o);
Since nobody mentioned it, the closest to instanceOf to Java by keyword is this:
obj.GetType().IsInstanceOfType(otherObj)

Difference between Convert.ToString() and .ToString()

What is the difference between Convert.ToString() and .ToString()?
I found many differences online, but what's the major difference?
Convert.ToString() handles null, while ToString() doesn't.
Calling ToString() on an object presumes that the object is not null (since an object needs to exist to call an instance method on it). Convert.ToString(obj) doesn't need to presume the object is not null (as it is a static method on the Convert class), but instead will return String.Empty if it is null.
In addition to other answers about handling null values, Convert.ToString tries to use IFormattable and IConvertible interfaces before calling base Object.ToString.
Example:
class FormattableType : IFormattable
{
private double value = 0.42;
public string ToString(string format, IFormatProvider formatProvider)
{
if (formatProvider == null)
{
// ... using some IOC-containers
// ... or using CultureInfo.CurrentCulture / Thread.CurrentThread.CurrentCulture
formatProvider = CultureInfo.InvariantCulture;
}
// ... doing things with format
return value.ToString(formatProvider);
}
public override string ToString()
{
return value.ToString();
}
}
Result:
Convert.ToString(new FormattableType()); // 0.42
new FormattableType().ToString(); // 0,42
Lets understand the difference via this example:
int i= 0;
MessageBox.Show(i.ToString());
MessageBox.Show(Convert.ToString(i));
We can convert the integer i using i.ToString () or Convert.ToString. So what’s the difference?
The basic difference between them is the Convert function handles NULLS while i.ToString () does not; it will throw a NULL reference exception error. So as good coding practice using convert is always safe.
You can create a class and override the toString method to do anything you want.
For example- you can create a class "MyMail" and override the toString method to send an email or do some other operation instead of writing the current object.
The Convert.toString converts the specified value to its equivalent string representation.
The methods are "basically" the same, except handling null.
Pen pen = null;
Convert.ToString(pen); // No exception thrown
pen.ToString(); // Throws NullReferenceException
From MSDN :
Convert.ToString Method
Converts the specified value to its equivalent string representation.
Object.ToString
Returns a string that represents the current object.
object o=null;
string s;
s=o.toString();
//returns a null reference exception for string s.
string str=convert.tostring(o);
//returns an empty string for string str and does not throw an exception.,it's
//better to use convert.tostring() for good coding
I agree with #Ryan's answer. By the way, starting with C#6.0 for this purpose you can use:
someString?.ToString() ?? string.Empty;
or
$"{someString}"; // I do not recommend this approach, although this is the most concise option.
instead of
Convert.ToString(someString);
In Convert.ToString(), the Convert handles either a NULL value or not but in .ToString() it does not handles a NULL value and a NULL reference exception error. So it is in good practice to use Convert.ToString().
For Code lovers this is the best answer.
.............. Un Safe code ...................................
Try
' In this code we will get "Object reference not set to an instance of an object." exception
Dim a As Object
a = Nothing
a.ToString()
Catch ex As NullReferenceException
Response.Write(ex.Message)
End Try
'............... it is a safe code..............................
Dim b As Object
b = Nothing
Convert.ToString(b)
Convert.ToString(strName) will handle null-able values and strName.Tostring() will not handle null value and throw an exception.
So It is better to use Convert.ToString() then .ToString();
ToString() can not handle null values and convert.ToString() can handle values which are null, so when you want your system to handle null value use convert.ToString().
ToString() Vs Convert.ToString()
Similarities :-
Both are used to convert a specific type to string i.e int to string, float to string or an object to string.
Difference :-
ToString() can't handle null while in case with Convert.ToString() will handle null value.
Example :
namespace Marcus
{
class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
class Startup
{
public static void Main()
{
Employee e = new Employee();
e = null;
string s = e.ToString(); // This will throw an null exception
s = Convert.ToString(e); // This will throw null exception but it will be automatically handled by Convert.ToString() and exception will not be shown on command window.
}
}
}
Here both the methods are used to convert the string but the basic difference between them is: Convert function handles NULL, while i.ToString() does not it will throw a NULL reference exception error. So as good coding practice using convert is always safe.
Let's see example:
string s;
object o = null;
s = o.ToString();
//returns a null reference exception for s.
string s;
object o = null;
s = Convert.ToString(o);
//returns an empty string for s and does not throw an exception.
Convert.ToString(value) first tries casting obj to IConvertible, then IFormattable to call corresponding ToString(...) methods. If instead the parameter value was null then return string.Empty. As a last resort, return obj.ToString() if nothing else worked.
It's worth noting that Convert.ToString(value) can return null if for example value.ToString() returns null.
See .Net reference source
i wrote this code and compile it.
class Program
{
static void Main(string[] args)
{
int a = 1;
Console.WriteLine(a.ToString());
Console.WriteLine(Convert.ToString(a));
}
}
by using 'reverse engineering' (ilspy) i find out 'object.ToString()' and 'Convert.ToString(obj)' do exactly one thing.
infact 'Convert.ToString(obj)' call 'object.ToString()' so 'object.ToString()' is faster.
Object.ToString Method:
class System.Object
{
public string ToString(IFormatProvider provider)
{
return Number.FormatInt32(this, null, NumberFormatInfo.GetInstance(provider));
}
}
Conver.ToString Method:
class System.Convert
{
public static string ToString(object value)
{
return value.ToString(CultureInfo.CurrentCulture);
}
}
Convert.Tostring() function handles the NULL whereas the .ToString() method does not. visit here.
In C# if you declare a string variable and if you don’t assign any value to that variable, then by default that variable takes a null value. In such a case, if you use the ToString() method then your program will throw the null reference exception. On the other hand, if you use the Convert.ToString() method then your program will not throw an exception.
Convert.Tostring() basically just calls the following value == null ? String.Empty: value.ToString()
(string)variable will only cast when there is an implicit or explicit operator on what you are casting
ToString() can be overriden by the type (it has control over what it does), if not it results in the name of the type
Obviously if an object is null, you can't access the instance member ToString(), it will cause an exception

What is the best practice for syntax in casting a variable?

Which (if any) is more correct? Why?
string someVariable = (string) someOtherVariable;
string someVariable = someOtherVariable.ToString();
string someVariable = someOtherVariable as string;
I've used all three, but I don't have any preference or understanding why one is better than the other.
These are not all examples of casting.
This is a cast:
string someVariable = (string) someOtherVariable;
This is method call:
string someVariable = someOtherVariable.ToString();
And this is a safe cast:
string someVariable = someOtherVariable as string;
The first and third examples are actual casts. The first cast has the potential to throw an InvalidCastException whereas the third example will not throw that exception. That is why the as operator is known as a safe cast.
Here's my article on the subject.
http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx
As for which one is "most correct", the one that is most correct is the one that has the meaning you intend to convey to the reader of the program.
"ToString()" conveys "this is probably not a string; if it is not, then I wish to obtain from the object a string which represents it."
The "cast" operator conveys either "this is a string, and I am willing to have my program crash if I am wrong", or the opposite, "this is not a string and I want to call a user-defined conversion on this object to string".
The "as" operator conveys "this might be a string and if it isn't, I want the result to be null."
Which of those four things do you mean?
The three do different things -- none are "more correct", it depends on your situation. If you have a bunch of objects that may not be strings, you'd probably use .ToString() (with a null check, if you expect nulls).
If you only care about the non-null strings, but still expect to be receiving non-strings, use an "as" cast, and then ignore the values that come in as null (they were either originally null, or of a non-string type)
if you expect to receive only strings, it is best to use the (string) cast. This expresses the intent best in the code.
object foo = 5;
string str = (string)foo; // exception
string str = foo as string; // null
string str = foo.ToString(); // "5"
object foo = "bar";
string str = (string)foo; // "bar"
string str = foo as string; // "bar"
string str = foo.ToString(); // "bar"
object foo = null;
string str = (string)foo; // null
string str = foo as string; // null
string str = foo.ToString(); // exception
The as keyword is very useful if you think the conversion will fail during an upcast. For instance, if I want to perform the same operation on similar types in a Control list... let's say unchecking all Checkboxes:
foreach (Control ctrl in Controls)
{
Checkbox box = ctrl as Checkbox;
if (box != null)
box.Checked = false;
}
This way, if my list has something else, like a text box or a label, no exception is thrown (as simply sets the variable = null if it fails), and it's very efficient. There is no exception overhead.
The ideas of CAST and CONVERT should not be confused here. Casting involves viewing an object as if it was another type. Converting involves transforming an object to another type.
If your intention is to CAST to a string, you should use the first or third. (Option depends on what you want to happen in the error condition. See bangoker's answer.)
If your intention is to CONVERT to a string, you should use the second. (Or better, ChaosPandion's modified statement with the trinary operator.) That is because the ToString method's behaviour is defined as converting the object into a string representation.
This is 100% personal preference here, but for me I use the folowing:
string someVariable = (string) someOtherVariable;
When converting to a child or parent type (eg. NetworkStream->Stream)
string someVariable = someOtherVariable.ToString();
When converting to a new type (int -> string)
And I never use the latter (as string) method, mostly because coming from a C/C++ background I prefer the() and it's a bit more concise.
There is a big difference between casting with parenthesis and casting with "as".
Basically, parenthesis will thrown an exception while "as" will return null instead of raising an exception.
More detailed info here
string someVariable = (string) someOtherVariable;
this is your good old normal casting and it will throw an exception if you try to cast something into something it CANNOT be casted (thus some times you need to check if they are castable)
string someVariable = someOtherVariable.ToString();
is not really casting, its executing a method that may come from different places(interfaces) but that ALL objects in C# have, since they inherit from the Object object, which has it. It has a default operation which is giving the name of the type of the object, but you can overload it to print whatever you want your class to print on the ToString method.
string someVariable = someOtherVariable as string;
This is a new c# casting, it will check first if it is castable by using a variable is string first and then doing the casting if it is valid or return null if it is not, so it could be a silent error if you are expecting exceptions, since you should check against null.
Basically
myType as myOtherType
is the same as:
var something = null;
if(myType is myOtherType)
{
something = (myType) myotherType;
}
except that as will check and cast in one step, and not in 2.
First of all, you should avoid casting with AS operator. The article linked explains why.
Second, you can use AS operator ONLY if you expect the value not being of the type you cast too. So you will have to check that manually.
Also the obj.ToString() method call is not a casting, it converts object to a string representation (which in case of a string itself is the same string). This can be ovveridden by any class.
So as a general rule I follow this:
Always use (Type) casting.
Use as operator only if object can be of other type than you cast to.
If using as operator - ALWAYS check the result for NULL.
UseToString only in cases when you need to display information about the object.
If your question about the best practice for syntax in casting a variable, then I prefer to use next one:
var someVariable = someOtherVariable as string ?? string.Empty;
Off course you can use someVariableDefaultValue instead of string.Empty.
In case if you cast not to string but into the some complex type, then I recommend next syntax, sometimes called the Safe Navigation Operator:
var complexVariable = otherComplexVariable as ComplexType;
if (complexVariable?.IsCondition)
{
//your code if cast passed and IsCondition is true
}
else
{
//your code if cast not passed or IsCondition is false
}

Casting to string versus calling ToString

object obj = "Hello";
string str1 = (string)obj;
string str2 = obj.ToString();
What is the difference between (string)obj and obj.ToString()?
(string)obj casts obj into a string. obj must already be a string for this to succeed.
obj.ToString() gets a string representation of obj by calling the ToString() method. Which is obj itself when obj is a string. This (should) never throw(s) an exception (unless obj happens to be null, obviously).
So in your specific case, both are equivalent.
Note that string is a reference type (as opposed to a value type). As such, it inherits from object and no boxing ever occurs.
If its any help, you could use the 'as' operator which is similar to the cast but returns null instead of an exception on any conversion failure.
string str3 = obj as string;
At the most basic level:
(string)obj will attempt to cast obj to a string and will fail if there's no valid conversion.
obj.ToString() will return a string that the designer of obj has decided represents that object. By default it returns the class name of obj.
(string)obj cast the object and will fail if obj is not null and not a string.
obj.ToString() converts obj to a string (even if it is not a string), it will fail is obj is null as it's a method call.
ToString() is object class method (the main parent class in .net) which can be overloaded in your class which inherits from object class even if you didn't inherited from it.
(string) is casting which can be implemented in the class it self, the string class so you don't have ability on it.

Better way to cast object to int

This is probably trivial, but I can't think of a better way to do it. I have a COM object that returns a variant which becomes an object in C#. The only way I can get this into an int is
int test = int.Parse(string.Format("{0}", myobject))
Is there a cleaner way to do this? Thanks
You have several options:
(int) — Cast operator. Works if the object already is an integer at some level in the inheritance hierarchy or if there is an implicit conversion defined.
int.Parse()/int.TryParse() — For converting from a string of unknown format.
int.ParseExact()/int.TryParseExact() — For converting from a string in a specific format
Convert.ToInt32() — For converting an object of unknown type. It will use an explicit and implicit conversion or IConvertible implementation if any are defined.
as int? — Note the "?". The as operator is only for reference types, and so I used "?" to signify a Nullable<int>. The "as" operator works like Convert.To____(), but think TryParse() rather than Parse(): it returns null rather than throwing an exception if the conversion fails.
Of these, I would prefer (int) if the object really is just a boxed integer. Otherwise use Convert.ToInt32() in this case.
Note that this is a very general answer: I want to throw some attention to Darren Clark's response because I think it does a good job addressing the specifics here, but came in late and wasn't voted as well yet. He gets my vote for "accepted answer", anyway, for also recommending (int), for pointing out that if it fails (int)(short) might work instead, and for recommending you check your debugger to find out the actual runtime type.
The cast (int) myobject should just work.
If that gives you an invalid cast exception then it is probably because the variant type isn't VT_I4. My bet is that a variant with VT_I4 is converted into a boxed int, VT_I2 into a boxed short, etc.
When doing a cast on a boxed value type it is only valid to cast it to the type boxed.
Foe example, if the returned variant is actually a VT_I2 then (int) (short) myObject should work.
Easiest way to find out is to inspect the returned object and take a look at its type in the debugger. Also make sure that in the interop assembly you have the return value marked with MarshalAs(UnmanagedType.Struct)
Convert.ToInt32(myobject);
This will handle the case where myobject is null and return 0, instead of throwing an exception.
Use Int32.TryParse as follows.
int test;
bool result = Int32.TryParse(value, out test);
if (result)
{
Console.WriteLine("Sucess");
}
else
{
if (value == null) value = "";
Console.WriteLine("Failure");
}
Maybe Convert.ToInt32.
Watch out for exception, in both cases.
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;
I am listing the difference in each of the casting ways. What a particular type of casting handles and it doesn't?
// object to int
// does not handle null
// does not handle NAN ("102art54")
// convert value to integar
int intObj = (int)obj;
// handles only null or number
int? nullableIntObj = (int?)obj; // null
Nullable<int> nullableIntObj1 = (Nullable<int>)obj; // null
// best way for casting from object to nullable int
// handles null
// handles other datatypes gives null("sadfsdf") // result null
int? nullableIntObj2 = obj as int?;
// string to int
// does not handle null( throws exception)
// does not string NAN ("102art54") (throws exception)
// converts string to int ("26236")
// accepts string value
int iVal3 = int.Parse("10120"); // throws exception value cannot be null;
// handles null converts null to 0
// does not handle NAN ("102art54") (throws exception)
// converts obj to int ("26236")
int val4 = Convert.ToInt32("10120");
// handle null converts null to 0
// handle NAN ("101art54") converts null to 0
// convert string to int ("26236")
int number;
bool result = int.TryParse(value, out number);
if (result)
{
// converted value
}
else
{
// number o/p = 0
}
There's also TryParse.
From MSDN:
private static void TryToParse(string value)
{
int number;
bool result = Int32.TryParse(value, out number);
if (result)
{
Console.WriteLine("Converted '{0}' to {1}.", value, number);
}
else
{
if (value == null) value = "";
Console.WriteLine("Attempted conversion of '{0}' failed.", value);
}
}
Strange, but the accepted answer seems wrong about the cast and the Convert in the mean that from my tests and reading the documentation too it should not take into account implicit or explicit operators.
So, if I have a variable of type object and the "boxed" class has some implicit operators defined they won't work.
Instead another simple way, but really performance costing is to cast before in dynamic.
(int)(dynamic)myObject.
You can try it in the Interactive window of VS.
public class Test
{
public static implicit operator int(Test v)
{
return 12;
}
}
(int)(object)new Test() //this will fail
Convert.ToInt32((object)new Test()) //this will fail
(int)(dynamic)(object)new Test() //this will pass
You can first cast object to string and then cast the string to int;
for example:
string str_myobject = myobject.ToString();
int int_myobject = int.Parse(str_myobject);
this worked for me.
int i = myObject.myField.CastTo<int>();
This worked for me, returning 0 also when myobject contains a DBNull
int i = myobject.ToString().Cast<int>().FirstOrDefault();

Categories

Resources