In C++ is assumed to be false while all other values are true. I was under the impression that in C# this concept was the same.
I'm trying to convert a char to a bool.
char c = (char)0;
Convert.ToBoolean(c).Dump();
It seems like no matter what char I try to convert I always get an error
Invalid cast from 'Char' to 'Boolean
I understand what I can to to fix this if I write my own custom function, but what I am trying to understand is.
What is the purpose of this method, What Char value converts to Bool?
You stated:
I was under the impression that in C# this concept was the same.
You were mistaken. It isn't. The two languages behave differently in that way, and you simply cannot convert a Char to a Boolean.
The documentation makes it clear that the method always fails:
Calling this method always throws InvalidCastException.
and...
Return Value
Type: System.Boolean
This conversion is not supported. No value is returned.
As evidenced by the source for Char.ToBoolean():
[__DynamicallyInvokable]
bool IConvertible.ToBoolean(IFormatProvider provider)
{
object[] values = new object[] { "Char", "Boolean" };
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", values));
}
As the Char class inherits from IConvertible, it is required to provide the overload. But since this conversion is not possible, an exception is always returned.
Just to show how it can be done with unsafe keyword (similar to c++). Don't use this..
char c = (char)0;
unsafe{
bool b = *((bool *)&c);
}
What is the purpose of this method...?
From the .NET 2.0 documentation:
This method is reserved for future use.
Perhaps they were considering implementing it along the lines of C++ but eventually decided not to.
EDIT - IConvertible is not the reason
There seems to be some confusion about the char.ToBoolean() method.
((IConvertible)someChar).ToBoolean(...);
is a separate issue from Convert.ToBoolean. (Why the explicit conversion first - see here.) The former had to be implemented when char was made IConvertible. The latter could have simply not been created, so the question of why does that method (Convert.ToBoolean) exists seems to be answered only for backwards compatibility + the original intention.
(If I'm the one misunderstanding this - please let me know, of course.)
This should work:
Convert.ToBoolean(Convert.ToInt32(charVar.ToString()))
Related
today I discovered a very strange behavior with C# function overloading. The problem occurs when I have a method with 2 overloads, one accepting Object and the other accepting Enum of any type. When I pass 0 as parameter, the Enum version of the method is called. When I use any other integer value, the Object version is called. I know this can be easilly fixed by using explicit casting, but I want to know why the compiler behaves that way. Is this a bug or just some strange language rule I don't know about?
The code below explains the problem (checked with runtime 2.0.50727)
Thanks for any help on this,
Grzegorz Kyc
class Program
{
enum Bar
{
Value1,
Value2,
Value3
}
static void Main(string[] args)
{
Foo(0);
Foo(1);
Console.ReadLine();
}
static void Foo(object a)
{
Console.WriteLine("object");
}
static void Foo(Bar a)
{
Console.WriteLine("enum");
}
}
It may be that you're not aware that there's an implicit conversion from a constant1 of 0 to any enum:
Bar x = 0; // Implicit conversion
Now, the conversion from 0 to Bar is more specific than the conversion from 0 to object, which is why the Foo(Bar) overload is used.
Does that clear everything up?
1 There's actually a bug in the Microsoft C# compiler which lets it be any zero constant, not just an integer:
const decimal DecimalZero = 0.0m;
...
Bar x = DecimalZero;
It's unlikely that this will ever be fixed, as it could break existing working code. I believe Eric Lippert has a two blog posts which go into much more detail.
The C# specification section 6.1.3 (C# 4 spec) has this to say about it:
An implicit enumeration conversion
permits the decimal-integer-literal 0
to be converted to any enum-type and
to any nullable-type whose underlying
type is an enum-type. In the latter
case the conversion is evaluated by
converting to the underlying enum-type
and wrapping the result (§4.1.10).
That actually suggests that the bug isn't just in allowing the wrong type, but allowing any constant 0 value to be converted rather than only the literal value 0.
EDIT: It looks like the "constant" part was partially introduced in the C# 3 compiler. Previously it was some constant values, now it looks like it's all of them.
I know I have read somewhere else that the .NET system always treats zero as a valid enumeration value, even if it actually isn't. I will try to find some reference for this...
OK, well I found this, which quotes the following and attributes it to Eric Gunnerson:
Enums in C# do dual purpose. They are used for the usual enum use, and they're also used for bit fields. When I'm dealing with bit fields, you often want to AND a value with the bit field and check if it's true.
Our initial rules meant that you had to write:
if ((myVar & MyEnumName.ColorRed) != (MyEnumName) 0)
which we thought was difficult to read. One alernative was to define a zero entry:
if ((myVar & MyEnumName.ColorRed) != MyEnumName.NoBitsSet)
which was also ugly.
We therefore decided to relax our rules a bit, and permit an implicit conversion from the literal zero to any enum type, which allows you to write:
if ((myVar & MyEnumName.ColorRed) != 0)
which is why PlayingCard(0, 0) works.
So it appears that the whole reason behind this was to simply allow equating to zero when checking flags without having to cast the zero.
The following is valid in c# as Char can be implicitly cast to int
int i = 'a';
i am just curious about what .Net Framework do behind the scenes, i looked in to char and int types source code but unable to find where it's written.
Can any body explain what happens behind the scene?
In C# we have something that is called a Single-Rooted unified type system. That means every existing type is a subtype of one root type. Object in C#. So char or int is only short (alias) for System.Char and System.Int32. The conversion from an untyped Object to long or char (value types) is called (un)boxing.
This is a real difference compared to Java where there are the primitive types int,char.. and there is Object. Java classes like Int are wrapping the primitive types. https://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java
Because in C# everything is an Object (I am Object, for we are many!), all the value types implement IConvertible, as the others said.
And there is a mostly internally used enum TypeCode that is the runtime reflection info that is assigned to value type object´s like int. The Convert.To method´s are using this type information to do their job.
http://referencesource.microsoft.com/#mscorlib/system/convert.cs
The mscorlib (System namespace) can be found on github under https://github.com/dotnet/coreclr/tree/master/src/mscorlib/src/System
Further because value types are full objects (struct) lots of type/meta information is available during runtime.
C# is a safe(er) language compared to c++ for example. It does not allow unsafe impilict casts.
The cast from char to int is a widening. Int is bigger/has more space than char. It´s safe to cast.
But that´s why it is not the same as (int) 'a' like Joanvo wrote.
This is an explicit cast and you are forcing .Net to do it, no matter it´s safe or not.
For int i = 'a'; it´s fine to do an implicit cast because of the widening.
But if you try char c = 42; Visual Studio and the compiler will not allow it. Unless you force it with an explicit cast while being aware that maybe not all information from the int will fit into the char
This is also the reason why you can not use something different than a boolean (expression) inside an if.
In C/C++ you can write if(1) { } or if(0) {}. That is not allowed in C#, where you have to write if(..==1) {}. In C/C++ this is often used to check pointer for null.
You can overload the implicit and explicit operator for own types, which is useful sometimes. At least useful to know it is possible.
https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx
As #shahwat and #joanvo said its the ASCII value that will be stored in i.
See this,
char value = 'a';
Console.WriteLine(value);
Console.WriteLine((int)value);
Console.WriteLine(value == 'y');
Console.WriteLine(value.GetType());
Console.WriteLine(typeof(char));
Console.WriteLine((int)char.MinValue);
Console.WriteLine((int)char.MaxValue);
Out Put:
a
97 (Integer value of char)
False
System.Char
System.Char
0 (MinValue as an integer)
65535 (MaxValue as an integer)
Edit:
microsoft
On this microsoft reference you can find the implementation of every method.
Just need to click on specific method and you will be navigated to the defination of that method.
You can also add specific VS extension related to your requirement
For ex:
Download VS extensions
by this way you would have a functionality in your VS and you can see the implementation by just right cicking on the methods and selecting "Go to Defination"
For your scenario
int i ='a';
This is not really a method (in some sense).
To view its implementation you have to use
roslyn
I am not sure would this be possible in case of Resharper , but i have just provided a way by which you can get this done.Hope this would be some help to you.
Here is a step by step guide for your scenario:
1.Setup Environment (Install VS,Roslyn) here
roslyn
2.Enable .NET Framework Source debug (if its not enabled by default)
Enable Source Debug
3.Put a break point on your statement int i='a'
4.Press f11 to step through all the implementation which is written behind this statement.
Thats all you have to do.
Imp note:
I would like to add one more thing that if above method does not worked for you ,then it would be something related to MSIL.So in that case you need to analyse what Roslyn generates from this code.
And if this is the case then you can also check it with any Reflector tool that will show you the generated MSIL.
The source code for the .NET primitive types is at http://referencesource.microsoft.com/, as indicated by #Sadaquat.
The specific implementation you're talking about is probably the implementation of IConvertable.ToInt32() from the Char struct.
That simply returns Convert.ToInt32(char value), which itself simply returns the value, since chars are integer values behind the scenes.
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.
today I discovered a very strange behavior with C# function overloading. The problem occurs when I have a method with 2 overloads, one accepting Object and the other accepting Enum of any type. When I pass 0 as parameter, the Enum version of the method is called. When I use any other integer value, the Object version is called. I know this can be easilly fixed by using explicit casting, but I want to know why the compiler behaves that way. Is this a bug or just some strange language rule I don't know about?
The code below explains the problem (checked with runtime 2.0.50727)
Thanks for any help on this,
Grzegorz Kyc
class Program
{
enum Bar
{
Value1,
Value2,
Value3
}
static void Main(string[] args)
{
Foo(0);
Foo(1);
Console.ReadLine();
}
static void Foo(object a)
{
Console.WriteLine("object");
}
static void Foo(Bar a)
{
Console.WriteLine("enum");
}
}
It may be that you're not aware that there's an implicit conversion from a constant1 of 0 to any enum:
Bar x = 0; // Implicit conversion
Now, the conversion from 0 to Bar is more specific than the conversion from 0 to object, which is why the Foo(Bar) overload is used.
Does that clear everything up?
1 There's actually a bug in the Microsoft C# compiler which lets it be any zero constant, not just an integer:
const decimal DecimalZero = 0.0m;
...
Bar x = DecimalZero;
It's unlikely that this will ever be fixed, as it could break existing working code. I believe Eric Lippert has a two blog posts which go into much more detail.
The C# specification section 6.1.3 (C# 4 spec) has this to say about it:
An implicit enumeration conversion
permits the decimal-integer-literal 0
to be converted to any enum-type and
to any nullable-type whose underlying
type is an enum-type. In the latter
case the conversion is evaluated by
converting to the underlying enum-type
and wrapping the result (§4.1.10).
That actually suggests that the bug isn't just in allowing the wrong type, but allowing any constant 0 value to be converted rather than only the literal value 0.
EDIT: It looks like the "constant" part was partially introduced in the C# 3 compiler. Previously it was some constant values, now it looks like it's all of them.
I know I have read somewhere else that the .NET system always treats zero as a valid enumeration value, even if it actually isn't. I will try to find some reference for this...
OK, well I found this, which quotes the following and attributes it to Eric Gunnerson:
Enums in C# do dual purpose. They are used for the usual enum use, and they're also used for bit fields. When I'm dealing with bit fields, you often want to AND a value with the bit field and check if it's true.
Our initial rules meant that you had to write:
if ((myVar & MyEnumName.ColorRed) != (MyEnumName) 0)
which we thought was difficult to read. One alernative was to define a zero entry:
if ((myVar & MyEnumName.ColorRed) != MyEnumName.NoBitsSet)
which was also ugly.
We therefore decided to relax our rules a bit, and permit an implicit conversion from the literal zero to any enum type, which allows you to write:
if ((myVar & MyEnumName.ColorRed) != 0)
which is why PlayingCard(0, 0) works.
So it appears that the whole reason behind this was to simply allow equating to zero when checking flags without having to cast the zero.
The following code throws an compile-time error like
Cannot convert type 'string' to 'int'
string name = Session["name1"].ToString();
int i = (int)name;
whereas the code below compiles and executes successfully:
string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);
I would like to know:
Why does the the first code generate a compile-time error?
What's the difference between the 2 code snippets?
(int)foo is simply a cast to the Int32 (int in C#) type. This is built into the CLR and requires that foo be a numeric variable (e.g. float, long, etc.) In this sense, it is very similar to a cast in C.
Convert.ToInt32 is designed to be a general conversion function. It does a good deal more than casting; namely, it can convert from any primitive type to a int (most notably, parsing a string). You can see the full list of overloads for this method here on MSDN.
And as Stefan Steiger mentions in a comment:
Also, note that on a numerical level, (int) foo truncates foo (ifoo = Math.Floor(foo)), while Convert.ToInt32(foo) uses half to even rounding (rounds x.5 to the nearest EVEN integer, meaning ifoo = Math.Round(foo)). The result is thus not just implementation-wise, but also numerically not the same.
(this line relates to a question that was merged) You should never use (int)someString - that will never work (and the compiler won't let you).
However, int int.Parse(string) and bool int.TryParse(string, out int) (and their various overloads) are fair game.
Personally, I mainly only use Convert when I'm dealing with reflection, so for me the choice is Parse and TryParse. The first is when I expect the value to be a valid integer, and want it to throw an exception otherwise. The second is when I want to check if it is a valid integer - I can then decide what to do when it is/isn't.
To quote from this Eric Lippert article:
Cast means two contradictory things: "check to see if this object really is of this type, throw if it is not" and "this object is not of the given type; find me an equivalent value that belongs to the given type".
So what you were trying to do in 1.) is assert that yes a String is an Int. But that assertion fails since String is not an int.
The reason 2.) succeeds is because Convert.ToInt32() parses the string and returns an int. It can still fail, for example:
Convert.ToInt32("Hello");
Would result in an Argument exception.
To sum up, converting from a String to an Int is a framework concern, not something implicit in the .Net type system.
A string cannot be cast to an int through explicit casting. It must be converted using int.Parse.
Convert.ToInt32 basically wraps this method:
public static int ToInt32(string value)
{
if (value == null)
{
return 0;
}
return int.Parse(value, CultureInfo.CurrentCulture);
}
You're talking about a C# casting operation vs .NET Conversion utilities
C# Language-level casting uses parenthesis - e.g. (int) - and conversion support for it is limited, relying on implicit compatibility between the types, or explicitly defined instructions by the developer via conversion operators.
Many conversion methods exist in the .NET Framework, e.g. System.Convert, to allow conversion between same or disparate data types.
(Casting) syntax works on numeric data types, and also on "compatible" data types. Compatible means data types for which there is a relationship established through inheritance (i.e. base/derived classes) or through implementation (i.e. interfaces).
Casting can also work between disparate data types that have conversion operators defined.
The System.Convert class on the other hand is one of many available mechanisms to convert things in the general sense; it contains logic to convert between disparate, known, data types that can be logically changed from one form into another.
Conversion even covers some of the same ground as casting by allowing conversion between similar data types.
Remember that the C# language has its own way of doing some things.
And the underlying .NET Framework has its own way of doing things, apart from any programming language.
(Sometimes they overlap in their intentions.)
Think of casting as a C# language-level feature that is more limited in nature, and conversion via the System.Convert class as one of many available mechanisms in the .NET framework to convert values between different kinds.
There is not a default cast from string to int in .NET. You can use int.Parse() or int.TryParse() to do this. Or, as you have done, you can use Convert.ToInt32().
However, in your example, why do a ToString() and then convert it back to an int at all? You could simply store the int in Session and retrieve it as follows:
int i = Session["name1"];
Just a brief extra: in different circumstances (e.g. if you're converting a double, &c to an Int32) you might also want to worry about rounding when choosing between these two. Convert.Int32 will use banker's rounding (MSDN); (int) will just truncate to an integer.
1) C# is type safe language and doesn't allow you to assign string to number
2) second case parses the string to new variable.
In your case if the Session is ASP.NET session than you don't have to store string there and convert it back when retrieving
int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];
This is already discussed but I want to share a dotnetfiddle.
If you are dealing with arithmetic operations and using float, decimal, double and so on, you should better use Convert.ToInt32().
using System;
public class Program
{
public static void Main()
{
double cost = 49.501;
Console.WriteLine(Convert.ToInt32(cost));
Console.WriteLine((int)cost);
}
}
Output
50
49
https://dotnetfiddle.net/m3ddDQ
Convert.ToInt32
return int.Parse(value, CultureInfo.CurrentCulture);
but (int) is type cast, so (int)"2" will not work since you cannot cast string to int. but you can parse it like Convert.ToInt32 do
The difference is that the first snippet is a cast and the second is a convert. Although, I think perhaps the compiler error is providing more confusion here because of the wording. Perhaps it would be better if it said "Cannot cast type 'string' to 'int'.
This is old, but another difference is that (int) doesn't round out the numbers in case you have a double ej: 5.7 the ouput using (int) will be 5 and if you use Convert.ToInt() the number will be round out to 6.