Posted By: Bas | Jun 19th, 2008 @ 7:00 AM
page 1 of 3
Comments: 52 | Views: 2395
Bas
Bas
It finds lightbulbs.
I know there's probably a really good reason for this, but I can't think of what it is, and it keeps bugging me. Why can't you do

int x = 10;
string y = (string)x;

in C#? I mean, you could simply use x.ToString(), but why doesn't the explicit cast do the same?
littleguru
littleguru
<3 Seattle
Because the explicit cast isn't implemented... ToString() is a general method (implemented in System.Object) and if string would implement the cast that would beg the question if all other classes need to implement it too...
Sven Groot
Sven Groot
My name has 9 letters. Coincidence? I think not...
I would guess it's because of locale and formatting issues. I never use CStr in VB because I'm just not quite sure what it'll end up doing.

I think this is the righ decision. Casts should be for straight type conversions, not for lexical conversions. That's just my opinion, though.
Yggdrasil
Yggdrasil
Pour me a cab, 'cause I can't drink no more.
I'm with Sven here. Casts aren't conversions, even though they could be overloaded to provide the same semantics, I think it's confusing. Casts should be just changing the glasses with which you look at a given object, rather than creating a new, different object. Like the way it works with interfaces or base classes. I'm not even fond of casts for native numeric types, like narrowing long->int casts. I would rather have a myLong.ToInt32() method, which is more explicit and less confusing. You can even add a ThrowOnNarrowingConversion argument if you'd like.
As you mentioned, implementing it for every class can't work, so they'd rather keep a coherent interface with ToString() rather than have you wonder whether a given type has implemented the explicit (string) cast or not.
littleguru
littleguru
<3 Seattle
That's also what I thought first... I only didn't write it because ToString() without parameters says also as much as a to-string-cast... But if we think about casts in general they are only there if you can easily convert types but not for things where you take external information into consideration to do the conversion; like cultural information etc.
figuerres
figuerres
???
well int to string is probably the one case that would work 99% of the time...

but say it was a case of DateTime to string.....

thre are about a zillion possible formats to use and many of the would be wrong most of the time....

that's why.
littleguru
littleguru
<3 Seattle
I guess they wanted to keep the whole framework consistent and therefore didn't implement it... and, for me, one great plus of the .NET Framework is its consistency; you really see that all seem to have followed the guidelines... not like other frameworks *cough* java *cough*

Edit: you know to avoid questions like: why is this working on int and not on datetime etc.
figuerres
figuerres
???

several reasons why ....

first off C# is not VB, some folks would howl and screem right there.

C family has always worked in a way that this case follows so this brings up a few questions like:

who would benefit? how much would they gain ?

what about explaining and teaching this to new programmers ?
very much an area that many would view as "not consistant" with the rest of the language.

also in what cases do you make it work / not work?

for example decimal, float and other numeric types when cast to a string might need to be formated as money
different cultures have different rules for that....
how does the compiler know what the right format is ??
how will it know what the runtime culture setting will be?
do you add that to the code you emit?
how much code does that add to the size of the dll / exe ?
how often will that be used if added (per call how often will the default work etc..)

even an int may need formating like "123,456"

granted you could "string it" then let the programmer parse the sting and then use it but then they would have been better off using a .ToString("") method in the first place.

so yes it might help with a few simple cases here and there but I think it would create more issues than it would solve.

it's part of why you and I still have a job... cause we can figure out which way to do this stuff  Smiley

littleguru
littleguru
<3 Seattle
Your reply lacks two things:
1) it's not the compiler who casts, but you implement a method to do that.
2) ToString() of Int32 is also doing some magic behind the scenes and you also need the knowledge that it will use the default culture.

Still, I wouldn't do it because ToString() is more explicit and you can see that it comes with overloads whereas the cast is something that should only cover simple cases...

I'll just answer with another question:

Why would you add another function (because explict casts are just functions anyway) that does exactly the same thing as ToString()?



And since I don't remember seeing a guideline about "explicit" we can take a look at the .NET Framework and see where it's most commonly used: Decimal, IntPtr, UIntPtr.

Why are these types using "explicit"? To allow casting to and from other numeric types. 
Is it OK that "explicit" is used? I'd say yes because conceptually all these types are just different implementations of a Number class so casting is done between "related" types.

Other cases of "explicit" in .NET Framework are Point <-> Size <-> Vector, Point3D <-> Size3D <-> Vector3D. Again we have strongly related types (so related that some other frameworks only have a Vector type).

The last case of "explict" usage is Nullable<T>. Needless to say, we have again a cast between related types.


Just my 2 (long) cents Smiley

Matthew van Eerde
Matthew van Eerde
AKA Maurits
Does
    string y = "" + x;
work?
That works. By dubious means.

The compiler tends to replace s1 + s2 + s3 ... with a call to String.Concat(s1, s2, s3...). String.Concat also has an overload which takes objects so you can concatenate a string with pretty much anything at the cost of boxing any involved value types. Better do x.ToString().
figuerres
figuerres
???

In any case it comes back to the same thing.

better to know what your conversion is doing than to guess.

and Casts are best for very basic / well defined types like number widening, or truncation

like

int16 y= 1024;

// super size me
 Int64  x = (Int64)y;

evildictaitor
evildictaitor
if( !succeed( try() ) ) { while(true) try(); }
There are those of us who work in compilers who strangle programmers who write things like that because it translates to

ldstr ""
ldtemp [x]
callvirt int32.ToString()
callvirt String.Concat()
sttemp [y]
littleguru
littleguru
<3 Seattle
Then use Convert.ToString(Int32) Tongue Out
littleguru
littleguru
<3 Seattle
You could implement an Extension Method to Int32: ToWellKnownString() Wink
evildictaitor
evildictaitor
if( !succeed( try() ) ) { while(true) try(); }
While in general you can't rely on undocumented features, you can be absolutely 100% sure that Microsoft will never change the (visible) implementation of System.Int32::ToString(). If Microsoft deems it nessisary to change the behaviour of the .ToString() method, it will do so via other methods, attributes or overloads, it will not change the visible implementation of int.ToString().

The simple reason for this is how much existing code relys on it. The fact that people here are advocating it as a way of converting from the 32 bit binary implementation to the ASCII base-10 representation shows that it is commonly used this way, and will continue to be used this way for quite some time. Beyond this, the fact that Int32 (as well as other types) are boxed when passed into object parameters which often rely on the .ToString() method (such as System.Console::Write, System.String::Format etc) means that if Int32::ToString() were to change then it would be a lot of grief for Microsoft.

Consequently I can confidently assure you that ((int)1987).ToString() will yield (string)"1987" for the forseeable future.
The documentation about SqlConnection.Close is as clear as it can be:

"If the SqlConnection goes out of scope, it won't be closed. Therefore, you must explicitly close the connection by calling Close or Dispose. Close and Dispose are functionally equivalent. If the connection pooling value Pooling is set to true or yes, the underlying connection is returned back to the connection pool. On the other hand, if Pooling is set to false or no, the underlying connection to the server is closed."
TommyCarlier
TommyCarlier
I want my scalps!

I never call Close() or Dispose() myself, either on a database connection or on a file or stream or anything that implements IDisposable. I almost always use the using-statement, like this:

using(SqlConnection lConnection = new SqlConnection(...))
{
    lConnection.Open();
    ... // use lConnection
}

page 1 of 3
Comments: 52 | Views: 2395
Microsoft Communities