whats the difference in the two string methods below?
string str1 = dr["RAGStatusCID"].ToString();
string str2 = (string)dr["Description"];
This will depend on what dr is. The first invokes the ToString method that each object could override on the indexer of the dr["RAGStatusCID"]. The second casts the dr["Description"] variable to a string.
If we use our telepathic skills and suppose that dr is a SqlDataReader then the two expression do pretty much the same thing except that the cast might throw an exception at runtime if the Description column is not a string.
You haven't mentioned the type of dr or what it's indexer operation returns, but ostensibly, these are two very different operations.
The first invokes the get indexer of dr and calls the ToString() method on the returned reference, allowing the object that reference refers to to provide a string representation of it's data. The generial intent of this is to allow the object itself to return a meaningful representation of itself as a string.
The second call attempts to cast the reference returned by the indexer to System.String. The object returned must either be an instance of System.String or must be a type that the compiler can invoke a custom conversion operator on. Here, the intent is to ensure that the object returned can be treated as an instance of System.String. You can read more about conversions (including user-defined ones) on MSDN.
First one calls the method that returns the string. Someone has to implement ToString method. Second one is just unboxing.
string str1 = dr["RAGStatusCID"].ToString();
This calls the .ToString() method on the object returned from the dr["RAGStatusCID"] call. It is guaranteed to return a string or null.
string str2 = (string)dr["Description"];
This attempts to cast the object returned by dr["Description"] to a string. If the object returned is not a string, then an exception is thrown.
in short, .toString() is a method, just like any other, (String) is a cast, a language construct used to treat one data type as another, compatible type.
Now for some detail:
.toString() is a method, just like any other method you may encounter. Its often thought to be a 'special' method in some way, but it isnt really, all it does is return a string. because its a member of the base Object type, it can be relied upon to be available in every object. For this reason it is generally used to provide a textual representation of the object of which it is member. By default, in c# this is the name of the type of the object. It is often desirable to override this method to provide a more meaningful name, but all it needs to do is return a string, this can be any string you like.
As noted before, theres nothing special about it, and you could just as easily have methods called ToInt(), ToDouble(), and ToChar() to provide the same functionality for there respective types.
Casting is a language construct, this means its built into the language and is implemented specifically for that language. It is used to enable compatible but different types to be used in different locations without the need for an explicit conversion.
xxx.ToString() calls a method on that object to convert it into a string object. (string)xxx assumes that the type of the object is already a string and simply performs a cast on the existing object. So in the first case a conversion happens, in the second it's just identifying the type explicitly.
To put it more succinctly, if in your example RagStatusCID is an integer and you attempted to call (string)dr["RagStatusCID"] you would get an exception because the type is not a string, it's an int. Calling .ToString() performs a conversion and the output is a string.
(string) is a casting operation. .ToString() is a method that is inherited from the Object class. Everything has a .ToString(), but not everything has a (string). Additionally certain objects will cast to a string different than the one .ToString() outputs.
I don't know if it is correct for C# but it probably is, so:
(String)myinstance calls implicitly the .toString() implementation of myinstance's class
if you have a class like this:
class User
{
private integer userId;
private integer userName;
... some code here...
public toString()
{
return "Username: " + this.userName + " (" + this.userId + ")";
}
}
with the method toString you are defining what (String)instance casting will do
User myuser = new User("Alex", 22);
String myuserdump = (String)myuser;
print(myuserdump);
will print "Username: Alex (22)"
Related
What's the difference between casting an Int to a string and the ToString() method ?
For example :-
int MyInt = 10;
label1.Text = (string)MyInt; // This Doesn't Work
label1.Text = MyInt.ToString(); // but this does.
Well, ToString() is just a method call which returns a string. It's defined in object so it's always valid to call on anything (other than a null reference).
The cast operator can do one of four things:
A predefined conversion, e.g. int to byte
An execution time reference conversion which may fail, e.g. casting object to string, which checks for the target object being an appropriate type
A user-defined conversion (basically calling a static method with a special name) which is known at compile-time
An unboxing conversion which may fail, e.g. casting object to int
In this case, you're asking the compiler to emit code to convert from int to string. None of the above options apply, so you get a compile-time error.
The difference is that with the cast, you ask the compiler to assume that the int is in fact a string, which is not the case.
With the ToString(), you ask for a string representation for the int, which is in fact a string :)
Um, ToString() is calling a method that returns a string representation of the integer.
When you cast, you are not returning a representation, you are saying that you want to reference the same object (well, value-type in this case) but you want to reference it as a different type.
A cast will only succeed if the type you are casting to (target type) is the same type as the object being cast or the target type is a superclass or interface of the cast object.
It is actually possible to do conversion in a cast providing the the source or target type declare implicit or explicit conversions, but the Int32 type does not do this for the String target type.
The .ToString() method is a method implemented on the System.Object type (from which all .NET types derive) and can be overridden on specific derived types.
Therefore the "int" type has it's own .ToString() method which knows all about ints, and how to convert them to a string representation.
With the (string)myint explicit cast, you are asking the compiler to forcefully convert/cast one type to another (in this case, an int into a string). It fails because the compiler says that a string and an int are incompatible types.
So, the explicit cast fails because the compiler says that an int is not a string, however the .ToString() call succeeds because the int type says that it's value can be represented as a string, and does so!
The ToString() method is one of the most usefull methods in programming and many other languages, such as Java, have the exact same method implemented at the Object level.
You can define your own and the signature in C# must always be this:
public override string ToString()
Which means this method will override the one define in the Object-class and returns a string. Inside, you manipulate your string in whichever way you want and then return the result.
Furthermore, the specific reason you can use ToString on that integer is because within C#, integers are all instances of the Struct Int32. Seeing as Int32 is at the same level of a class, it can have its own methods, one of which is ToString().
One more thing never use .ToString() if you think the object might be null or your application will crach example :
//Emulates the problem that might happen
object obj = null;
obj.ToString();
ddlSomeDropDownType.SelectedValue is a dropdown of .aspx page.
I have the following code:
int num = int.Parse(((object)this.ddlSomeDropDownType.SelectedValue).ToString());
Am I correct in thinking that the following happens:
Drop down value (string) gets down-casted to object
Object is a reference type so .ToString() doesn't do anything in this instance, gets omitted by the compiler
Object then gets parsed to int: ref type => value type
Or would the C# compiler pick up on that, and not cast when it doesn't have to?
drop down value (string) gets down-casted to object
Well, yes, but all that changes is how subsequent calls to the object are bound by the compiler. You're telling the compiler "treat this value as an object" It does not change the actual object in any way.
object is a reference type so .ToString() doesn't do anything in this instance, gets omitted by compiler
No - you call ToString which is a virtual method on object, so either object.ToString or a subsequent override will get called (in your case, string.ToString()`.
Plus, you've told the compiler to treat the value as an object. You expect the compiler to go back and say "well, I know you told me to treat it as an object, but I can tell from the code above that it's a string, so I'm going to ignore that and just keep it as a string". The compiler will not go to that effort. The JIT optimizer may do something similar if there is an iron-clad guarantee that it will work; otherwise it will do what you told it to do.
object than gets cast to int
No - it is parsed by the int class - very different than casting. It will read the characters of the string and attempt to return an equivalent integer value. The original object (the string) is untouched, and a new value (the int) is created. If you "change" the original value (which is impossible in this case because strings are immutable, but for sake of argument let's assume you can) then the parsed integer would not change. If you casted the object to int and then changed the string, they are both referencing the same value, so and changes would be reflected in both.
Since SelectedValue is a string, there's no need to cast to object and then call ToString(), so your code could be simplified to
int num = int.Parse(this.ddlDiscountType.SelectedValue);
No, not really.
First, you need to understand the difference between runtime type information and compile-time type information.
The compile-time type of ddlDiscountType.SelectedValue is string. When you cast it to object, it doesn't change the runtime type, just the compile-time type - in effect, you reduced the public interface of the reference.
ToString is a virtual method, so as long as you don't use new, what happens depends on the runtime type, and has no relation to the compile-time type, as long as the method is defined in the compile-time type. Since ToString is defined on Object, there's no problem.
The compiler cannot remove the call to ToString, because you've explicitly said "No, this reference is not really a string. It's just an object.", so you do have to make the virtual method call. The call will use the runtime type of the reference, so you're executing String.ToString(), which just returns this. But you did all your best to interfere with the compiler, and the compiler isn't going to second-guess you.
Finally, int.Parse will parse the string and output an integer. This involves going character by character through the string, of course. Reference and value types aren't important here - it's not a cast, it's a method call like any other. The method converts a string to a number, that's it. A cast would simply throw an InvalidCastException, because a string is not an integer (though if you make your own type, you can provide your own cast methods, which can do whatever you want them to do). The compiler can't tell you that you can't cast a string to an integer, because you just said the reference isn't really a string, but rather an object - and an object can be casted to a int, if it refers to a runtime type that is a boxed int.
There's no reason to do things in such a complicated manner. Just do:
var number = int.Parse(ddlDiscountType.SelectedValue);
Spend your effort in adding proper error handling instead of doing silly rituals :)
1: That's not correct. "Drop Down value (string) is Up-casted into object ".All classes in the .NET Framework are derived from object.(casting toward Base class is up-casting.)
2: a) Yes object is reference type.
b).ToString is object class method(can be override by derived classes). Actually what's going on here is that int.Parse takes string parameter. For that you first covert that into object and then .ToString method calls.
3:Yes 3rd point is correct
i want to know typecasting in c# .net, i have below lines of code.
int i=4
object o = i // This works properly without any typecasting becausing boxing takes place automatically
string s= i // This does not work, even when the string is also reference type?
string s=(string)i //This also does not work even if i try to typecast the int to string.
string s= Convert.ToString(i); // this works.
so i want to know why string s = i and string s = (string)i does not work and whats the difference in using (string)i, i.ToString(), and Convert.ToString(i).
When it comes to boxing and unboxing, types have explicit and implicit casting. So, in some circumstances, it is easy enough for the runtime to allow for implicit conversion between two supported types, say an Int32 to a Double. However, there is no implicit or explicit conversion between an integer and a string, because obviously, a string is not an integer (despite the fact that a string can contain characters for an integer).
string s = i; // attempt at implicit cast from Int32 to String, error
object o = i; // all types inherit from Object, so you may implicitly or explicitly cast from Int32 to Object.
s = (string)i; // attempt at explicit cast from Int32 to string, error
s = i.ToString(); // conversion
s = Convert.ToString(i); // conversion
That's where Convert comes to play. Convert contains support for attempting to convert known primitives (and types supporting IConvertable) to another. So, ToString or Convert.ToString would be the preferred methods (ToString and Convert.ToString are virtually synonymous, except that ToString gives you some formatting options).
Well, string and object - both of them are reference types. However, object is a root type for all .NET types.
When you use such syntax as (string)i, you are trying to use explicit conversion beetween types. But this conversion type requires string class to know about all possible argument types.
So we have .ToString() method, which can be overriden in any class, and its return value is used as a string represenation of any object.
string s = i and string s = (string)i does not work
because I is not a string, and type CASTING is a CAST of the type, not a conversion. It only works if i contains a string or a subclass of string (which is not possible for strings, but may be for other classes).
whats the difference in using (string)i, i.ToString(), and Convert.ToString(i).
(string) i: cast i to a string, must be assignable.
i.ToString(): calls the ToSstring method, which is defiend on System.object, thus available on ALL classes and structs - but returns no sensible content if not overwritten.
Convert.ToString(i): coonverts i to a string. THis includes calling a converter which likely just calls ToString on this rare case.
At the end, casting is not aconversion. for (string) i to work i HAS TO BE A STRING, while convert tries to MAKE it a string.
You can specify implicit and explicit conversions in .net, the reason that string s = i fails is that there is no built in cast operation for an integer to a string.
see this MSDN article on casting for further information
string s= i does not work because the types don't match, int won't go into a string.
string s=(string)i does not work because it cannot asume which type conversion is to be used (i.e which base)
something like s = ""+i would work on the other hand as it would asume base 10 conversion.
so i want to know why string s = i and string s = (string)i does not work
The short answer is that there is no implict (first example above) nor explicit (second example above) cast from int to string defined. Slightly longer answer; when authoring the struct Int32 in C# no casting behaviour was programmed to enable the developer to automagically cast from an int to a string
whats the difference in using (string)i, i.ToString(), and Convert.ToString(i)
Well, the first doesn;t work as you said, and as ive explained above. The second calls the ToString method on the struct Int32, which returns (as the name implies) a string representation of the object. It should be noted that this is a brand new string, not in any way related to the original value. The third example Convert.ToString will, under the hood, call whatever the most appropriate way to turn the parameter passed in to a string - most likely just calls the ToString method - so pretty much identical to example 2.
ToString() method is override by each referance which is vitual method in the object class. string calss override that method and provide string value out of this.
The default implementation of the ToString method returns the fully qualified name of the type of the Object, as the following example shows.
Object obj = new Object();
Console.WriteLine(obj.ToString());
// The example displays the following output:
// System.Object
this behavior is inherited by reference types that do not override the ToString method.
Typecasting in C# only works along the lines of class inheritance. Object is the root of all types in C# and therefore all values can be typecast to it.
string and int do not share the same branch of inheritance and so cannot be directly cast from one to the other.
Convert.ToString() is a method designed to convert an integer to a string - there's no typecasting going on, it's just executing a method designed to convert an integer to a string representation.
i.ToString() performs the equivalent functionality to Convert.ToString(), except that i.ToString() has overloads which allow greater flexibility on the representation of the number in string format.
One last note, exceptions to the typecasting rules can be included by the developer by using a public static explicit operator method which permits the developer to convert one value to another as they see fit.
First thing to note is that every class derives from object.
Casting int to object is using an Int32.
Casting string to object is using a String.
There is no implicit cast from an integer to a string because they are in different parts of the class hierarchy - one does not in any way relate to another. However because string is used so often for output object (and therefore all its children) have a ToString() method for convenience.
However Convert is written specifically to be able to convert from one type to another, for example Convert.ToBool(x) can parse "true" or "false" to boolean, and as you have shown it can convert an integer to a string - again this is really a convenience that probably just calls Int32.ToString() under the hood.
I have a question regarding type conversion in C#.
Object data_obj = "test";
string data_str;
data_str = data_obj;
this produces an error claiming no implicit conversion exists. Now, this is, at least for me, a little bit unintuitive, since Console.WriteLine("type{0}",data_obj.GetType()) produces System.String, but then again, i am really new at C#.
Now, getting past this, i would like to cast to the type of the data stored in data_obj, without having to switch and selecting the type manually.
So, basically, what i am asking is: is there a way to define an implicit conversion from System.Object to System.String, System.Decimal, etc.
Context:
I am reading from an ODBC connection to an SQLServer database and trying to pump those rows into an Oracle Database. Now, the correspondence of SQLServer and Oracle rows have to be defined. Now, i read the data from the SQLServer table with no problem whatsoever, and i store it in a List<Dictionary<string,Object>> (i know, storing the rows seem wrong, but design requirements, what can you do).
The insertion part is where i am having problems with the insertion. I basically loop (with a foreach) through the elements of the list and insert them row by row. It is here where i need to determine the type of the data stored in the Object.
Edit: Including a bit more detail.
No, there's no way of doing it implicitly. Options:
Call ToString() explicitly (which will throw an exception if the reference is null)
Call Convert.ToString()
Use "" + data_obj (ick, don't do it)
Cast if you're sure that data_obj is really a string
Why are you so keen on an implicit conversion though?
What you should be doing in your code as noted above is casting, not converting. The object in question is a string; you simply have stored it in an object reference.
Casting would be done like so:
data_str = (string)data_obj;
The overload of Console.Writeline you are mentioning takes a format string, and then a params array of object... not strings. It calls ToString() on each of those objects. So your call to data_obj.GetType().ToString() could be slimmed down to data_obj.GetType() (calling ToString() on a string just returns the string again)
As for an implicit conversion from object to type x... think about what you are asking; a reference of object can be any CLR type. How do you handle those conversions?
You could use the Convert.ToString method:
object o = ...
string s = Convert.ToString(o);
There is no implicit conversion from object to string in C#. However you could call the object's virtual ToString method
string s = o.ToString();
If you store your value in a var instead of type object and let the compiler decide what the value is, then it can be made implicit.
var data_obj = "test";
string data_str;
data_str = data_obj;
This isn't really an issue, however I am curious. When I save a string in lets say an DataRow, it is cast to Object. When I want to use it, I have to cast it ToString. As far as I know there are several ways of doing this, first is
string name = (string)DataRowObject["name"]; //valid since I know it's a string
and another one is:
string name = DataRowObject["name"].ToString();
I am interested in what is the difference between both? Is the first more efficient? (This is just a speculation, in my head ToString() method is implemented by some looping mechanism where just casting it "could" be faster, however this is just a "gut feeling" I have).
Is there even a faster / more elegant way of doing this?
Can anyone clear this up for me?
The two are intended for different
purposes. The ToString method of any
object is supposed to return a string
representation of that object. Casting
is quite different, and the 'as' key
word performs a conditional cast, as
has been said. The 'as' key word
basically says "get me a reference of
this type to that object if that
object is this type" while ToString
says "get me a string representation
of that object". The result may be the
same in some cases but the two should
never be considered interchangeable
because, as I said, they exist for
different purposes. If your intention
is to cast then you should always use
a cast, NOT ToString.
from http://www.codeguru.com/forum/showthread.php?t=443873
see also http://bytes.com/groups/net-c/225365-tostring-string-cast
If you know it is a String then by all means cast it to a String. Casting your object is going to be faster than calling a virtual method.
Edit: Here are the results of some benchmarking:
============ Casting vs. virtual method ============
cast 29.884 1.00
tos 33.734 1.13
I used Jon Skeet's BenchmarkHelper like this:
using System;
using BenchmarkHelper;
class Program
{
static void Main()
{
Object input = "Foo";
String output = "Foo";
var results
= TestSuite.Create("Casting vs. virtual method", input, output)
.Add(cast)
.Add(tos)
.RunTests()
.ScaleByBest(ScalingMode.VaryDuration);
results.Display(ResultColumns.NameAndDuration | ResultColumns.Score,
results.FindBest());
}
static String cast(Object o)
{
return (String)o;
}
static String tos(Object o)
{
return o.ToString();
}
}
So it appears that casting is in fact slightly faster than calling ToString().
Basically in your case it is better to leave type cast because .ToString() may hide bugs. For example, your data base schema changed and name is no longer of string type but with .ToString() your code still works. So in this case it is better to use type cast.
Here is implementation of String.ToString() - nothing special =)
public override string ToString()
{
return this;
}
Downcasting is a relatively slow operation since CLR has to perform various runtime type-checks. However, in this particular scenario casting to string is more appropriate than calling ToString() for the sake of consistency (you can't call ToInt32 on object, but cast it to int) and maintanability.
I want to make one more comment
If you are going to use casting: string name = (string)DataRowObject["name"]
you will get an Exception: Unable to cast object of type 'System.DBNull' to type'System.String' in case if the record in the database table has null value.
In this scenario you have to use: string name = DataRowObject["name"].ToString() or
You have to check for null value like
if(!string.IsNullOrEmpty(DataRowObject["name"].ToString()))
{
string name = (string)DataRowObject["name"];
}
else
{
//i.e Write error to the log file
string error = "The database table has a null value";
}
For data object, I suggest you to use "as" keyword like the following code.
string name = DataRowObject["name"] as string;
Please check it before you use value.
if(name != null)
{
// statement for empty string or it has value
}
else
{
// statement for no data in this object.
}
In this case:
string name = DataRowObject["name"].ToString();
since it is a string, I think that the ToString() method of a string object is simple as:
return this;
so IMHO there is no performance penalty.
PS
I'm a Java programmer, so this anwser is only a guess.
ToString() does not perform a cast by default. Its purpose is to return a string that represents the type (e.g. "System.Object").
If you want to avoid casting you could try to think of an implementation that is strongly typed (using generics, for example) and avoids DataRowObject altogether.
I know you mentioned that the Object is a string, but incase you're afraid that the returned object is null, you can also cast using "Convert.ToString(DataRowObject["name"]);" This has the added benefit of returning an empty string (string.empty) if the object is null, to avoid any null reference exceptions (unless of course you want an exception thrown in such cases).