casting and parsing between string, object and int - c#

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

Related

Object type is same as type in inherited class [duplicate]

C# newbie question here. The following code (taken from the book "C# From Novice to Professional" by Christian Gross, Apress) gives an error:
worksheet.Add("C3", CellFactories.DoAdd(worksheet["A2"], worksheet["B1"]));
The reason is that the method DoAdd() does not accept the given arguments.
public static Func<object> DoAdd(Func<object> cell1, Func<object> cell2) {...}
VS claims that both args in the method call above are of type object whereas the method accepts only Func<object>. But the value of both worksheet elements is of type Func<object>:
worksheet.Add("A2", CellFactories.Static(10.0));
where this Static method just returns the given value:
public static Func<object> Static(object value) { return () => value; }
// return type= Func<object>
When I cast worksheet["A2"] as Func<object>, the code does work.
But there is something I don't understand. The type of the object instance is Func<object>. I have used the GetType() method to see proof of this, and compare the object types of the original elements to that of the cast object (which IS accepted):
Console.Writeline(worksheet["A2"].GetType());
// now cast to the correct type (why can't it do that implicitly, btw?)
Funk1 = worksheet["A2"] as Func<object>;
Console.Writeline(Funk1.GetType());
.. and they are ALL identical! (Type = System.Func'1[System.Object])
And even when I use the .Equals() method to compare both types, it returns true.
Yet, VS sees the first object instance as type object in the method call. Why? Why does the called method 'see' the argument as a different type than the GetType() returns?
(and if so, what good is the GetType() method?)
Thanks a lot for your advice/comments! (It's kinda hard to learn the language if the book examples give an error and you don't see the reason - hence, got the vague impression that something is wrong either with GetType() or VS.)
You need to understand the difference between dynamic typing and static typing. The indexer for your worksheet object most likely has a static type of object.
public object this[string cell]{get{...}set{...}}
Because all objects in C# inherit from type object, the object reference stored in a cell can be a reference to any object.
That is, because a delegate (such as Func<T>) is an object, it can be stored in an object reference:
Func<object> func = ()=>return "foo";
object o = func; // this compiles fine
And the compiler can figure this all out, because it understands implicitly that a derived class can be stored in a reference to a base class.
What the compiler cannot do automatically, is determine what the dynamic type, or run time type of an object is.
Func<object> func = ()=>return "foo";
object o = func; // this compiles fine
func = o; // <-- ERROR
The compiler doesn't know that the object stored in o is actually of type Func<object>. It's not supposed to keep track of this. This is information that must be checked at run time.
func = (Func<object>)o; // ok!
The above line of code compiles into something that behaves similarly to this:
if(o == null)
func = null;
else if(typeof(Func<object>).IsAssignableFrom(func.GetType()))
__copy_reference_address__(func, o); // made up function! demonstration only
else throw new InvalidCastException();
In this way, any cast (conversion from one type to another) can be checked at run time to make sure it's valid and safe.
Others have given accurate and detailed answers, but here I will try to explain in simple language.
When you write worksheet["A2"] you really are calling a member function of worksheet
worksheet has a member function named [] that accepts a string and returns an object
The signature of the member function [] looks like object this[string id]
So the function worksheet["A2"] returns something that is an object. It could be an int or a string or many other things. All the compiler knows is that it will be an object.
In the example, you have it returning a Func<object>. This is fine, because Func<object> is an object. However, you then pass the result of that function in as a parameter to another function.
The problem here is that the compiler only knows that worksheet["A2"] returns an object. That is as specific as the compiler can be.
So the compiler sees that worksheet["A2"] is an object, and you are trying to pass the object to a function that does not accept object as a parameter.
So here you have to tell the compiler "hey dummy, that's a Func<object>" by casting the returned object to the correct type.
worksheet.Add("C3", CellFactories.DoAdd(worksheet["A2"], worksheet["B1"]));
can be re-written as
worksheet.Add("C3", CellFactories.DoAdd((Func<object>)worksheet["A2"], (Func<object>)worksheet["B1"]));
Now the compiler knows that, even though the [] function returns an object, it can treat it like a Func<object>.
side note: You're probably doing too much on one line. That may be hard for people to read in the future.
Why does the called method 'see' the argument as a different type than the GetType() returns?
The compiler only knows that worksheet[] returns an object. The compiler can not call GetType() on it at compile time.
What good is the GetType() method?
There are quite a few uses and abuses of the GetType() method, but that is an entirely different discussion. ;)
In summary, the compiler does not assume anything about types. This is a good thing because you get a compile time error when you try to fit this square peg into a round hole. If the compiler did not complain, this error would surface at run-time, which means you would probably need a unit test to detect the problem.
You can get around this problem by telling the compiler "I know for a fact that this thing is a round peg, trust me." and then it will compile.
If you lie to the compiler, you will get a run-time error when that code is executed.
This is called "static typing". The opposing philosophy is called "dynamic typing" where type checks are done at run-time. Static vs dynamic is a lengthy debate and you should probably research it on your own if you're interested.
VS claims that both args in the method call above are of type object whereas the method accepts only Func. But the value of both worksheet elements is of type Func
Yes, but the declared type is object. The compiler can't know that the actual runtime type will be Func<object>, so an explicit cast is necessary.

why isn't there a explicit typecast to string in c# [duplicate]

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();

type casting in c#.net

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.

What is the difference between xxx.tostring() and (string)xxx?

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)"

Difference between dynamic and System.Object

What is the difference between a variable declared as dynamic and a variable declared as System.Object? Running the following function would seem to indicate that both variables get cast to the correct type dynamically:
void ObjectTest()
{
System.Object MyTestVar = "test";
dynamic MyTestVar2 = "Testing 123";
Console.WriteLine("{0}", MyTestVar.GetType());
Console.WriteLine("{0}", MyTestVar2.GetType());
MyTestVar = 123;
MyTestVar2 = 321;
Console.WriteLine("{0}", MyTestVar.GetType());
Console.WriteLine("{0}", MyTestVar2.GetType());
}
The difference is that MyTestVar2.ToUpper() compiles and works, without any explicit casting.
object is a normal type.
dynamic is a basically a placeholder type that causes the compiler to emit dynamic late-bound calls.
GetType() is a normal function defined by the object class that operates on the instance that you call it on.
GetType() is completely unaffected by the declared type of a variable that refers to the object you call it on. (except for nullables)
You should probably start with this excellent MSDN article. The differences can be summed up quite succinctly:
At compile time, an element that is
typed as dynamic is assumed to support
any operation.
System.Object only has a handful of operations that it supports - ToString(), Equals(), etc.
The fundamental difference is compile-time(for object) vs runtime (for dynamic) resoulution of calls. Its also called early vs late binding. [ Note: add a reference to Microsoft.CSharp for the following code to compile.]
object o = "Hello world";// fine because a derived type can be assigned to a base type
dynamic d= "Hello world";// fine as well
Type otype=o.GetType();// compiles because it confirms that object has a GetType()
Type dtype=d.GetType();// also compiles but for another reason (i.e.no binding yet)
string upperd= d.ToUpper(); // compiles because no binding yet ( anything goes :)
string uppero= o.ToUpper(); // Fails to compile. Object has no ToUpper() method
If you comment out the last call , the application should run fine because the CLR , when it reaches the second last call d.ToUpper() at runtime, it will look for a method ToUpper() in the string type and will find it there (because in the second statement d was assigned a string). The last call did not compile because ToUpper() was being searched in the System.Object type at the compile time which of course will not be there.
The only difference in between object and dynamic.
In case of object you need to explicit type cast when you are going to retrieve value from object.
Kindly give a like if you find it suitable.

Categories