true.ToString()
false.toString();
Output:
True
False
Is there a valid reason for it being "True" and not "true"? It breaks when writing XML as XML's boolean type is lower case, and also isn't compatible with C#'s true/false (not sure about CLS though).
Update
Here is my very hacky way of getting around it in C# (for use with XML)
internal static string ToXmlString(this bool b)
{
return b.ToString().ToLower();
}
Of course that adds 1 more method to the stack, but removes ToLowers() everywhere.
Only people from Microsoft can really answer that question. However, I'd like to offer some fun facts about it ;)
First, this is what it says in MSDN about the Boolean.ToString() method:
Return Value
Type: System.String
TrueString if the value of this
instance is true, or FalseString if
the value of this instance is false.
Remarks
This method returns the
constants "True" or "False". Note that
XML is case-sensitive, and that the
XML specification recognizes "true"
and "false" as the valid set of
Boolean values. If the String object
returned by the ToString() method
is to be written to an XML file, its
String.ToLower method should be
called first to convert it to
lowercase.
Here comes the fun fact #1: it doesn't return TrueString or FalseString at all. It uses hardcoded literals "True" and "False". Wouldn't do you any good if it used the fields, because they're marked as readonly, so there's no changing them.
The alternative method, Boolean.ToString(IFormatProvider) is even funnier:
Remarks
The provider parameter is reserved. It does not participate in the execution of this method. This means that the Boolean.ToString(IFormatProvider) method, unlike most methods with a provider parameter, does not reflect culture-specific settings.
What's the solution? Depends on what exactly you're trying to do. Whatever it is, I bet it will require a hack ;)
...because the .NET environment is designed to support many languages.
System.Boolean (in mscorlib.dll) is designed to be used internally by languages to support a boolean datatype. C# uses all lowercase for its keywords, hence 'bool', 'true', and 'false'.
VB.NET however uses standard casing: hence 'Boolean', 'True', and 'False'.
Since the languages have to work together, you couldn't have true.ToString() (C#) giving a different result to True.ToString() (VB.NET). The CLR designers picked the standard CLR casing notation for the ToString() result.
The string representation of the boolean true is defined to be Boolean.TrueString.
(There's a similar case with System.String: C# presents it as the 'string' type).
For Xml you can use XmlConvert.ToString method.
It's simple code to convert that to all lower case.
Not so simple to convert "true" back to "True", however.
true.ToString().ToLower()
is what I use for xml output.
How is it not compatible with C#? Boolean.Parse and Boolean.TryParse is case insensitive and the parsing is done by comparing the value to Boolean.TrueString or Boolean.FalseString which are "True" and "False".
EDIT: When looking at the Boolean.ToString method in reflector it turns out that the strings are hard coded so the ToString method is as follows:
public override string ToString()
{
if (!this)
{
return "False";
}
return "True";
}
I know the reason why it is the way it is has already been addressed, but when it comes to "custom" boolean formatting, I've got two extension methods that I can't live without anymore :-)
public static class BoolExtensions
{
public static string ToString(this bool? v, string trueString, string falseString, string nullString="Undefined") {
return v == null ? nullString : v.Value ? trueString : falseString;
}
public static string ToString(this bool v, string trueString, string falseString) {
return ToString(v, trueString, falseString, null);
}
}
Usage is trivial. The following converts various bool values to their Portuguese representations:
string verdadeiro = true.ToString("verdadeiro", "falso");
string falso = false.ToString("verdadeiro", "falso");
bool? v = null;
string nulo = v.ToString("verdadeiro", "falso", "nulo");
This probably harks from the old VB NOT .Net days when bool.ToString produced True or False.
Related
What would be required to create a case-insensitive string type that otherwise behaves exactly like a string?
I've never heard of anyone making a case insensitive string type like this and it's obviously not part of the framework, but it seems like it could be very useful. The fact that SQL does case insensitive comparisons by default is a great case in point. So I'm thinking it's either not possible, or else there's a really good reason why no one does it that I'm not aware of.
I know it would require using an implicit operator for assignment, and you would have to override the equals operator. And for overriding GetHashCode(), I'm thinking you could just return ToLower().GetHashCode().
What am I missing?
Comparing string is rather easy. You can simply use the equals method or the compare method.
Example:
string s = "A";
s.Equals("a", StringComparison.InvariantCultureIgnoreCase); // Will return true.
string s = "A";
s.Equals("a", StringComparison.InvariantCulture); // Will return false.
You should also look at this. That will explain a little more on comparing strings.
Building on type of deathismyfriend's answer above, I would extend the string class:
public static class StringExtensions
{
public static int CaseInsensitveCompare(this string s, string stringToCompare)
{
return String.Compare(s, stringToCompare, StringComparison.InvariantCultureIgnoreCase);
}
}
And the call:
int result = firstString.CaseInsensitveCompare(secondString);
It wouldn't behave "exactly like a string". The string type is special and is baked into the language spec. C# strings exhibit special behavior, such as
being a reference type, that gets passed by value. Reference types are normally passed by...well...reference.
are interned by default. That means that there is only ever a single instance of a given string. The following code results in the creation of just a single string: a, b and c all point to exactly the same instance of the string quick. That means that Object.ReferenceEquals() is true when comparing any two:
string a = "The quick brown dog...".Substring(4,5) ;
string b = new string(new char[]{'q','u','i','c','k'});
string c = new StringBuilder().
.Append('q')
.Append('u')
.Append('i')
.Append('c')
.Append('k')
.ToString()
;
[edited to note: while one might think that this should be possible, a little fiddling around suggests that one can't actually create a custom implementation/subtype of CompareInfo as it has no public constructors and its default constructor is internal. More in the answers to this question: Globally set String.Compare/ CompareInfo.Compare to Ordinal
Grrr...]
What you could do is this:
String comparisons are done using the current culture's collation/comparison rules. Create a custom culture for your app, say, a copy of the the US culture that uses the collation/comparison rules you need. Set that as the current culture and Bob's-yer-uncle.
You'll still get compiler/ReSharper whines because you're doing string comparisons without specifying the desired comparison semantics, but your code will be clean.
For more details, see
https://msdn.microsoft.com/en-us/library/kzwcbskc(v=vs.90).aspx
https://msdn.microsoft.com/en-us/library/se513yha(v=vs.100).aspx
In my Java days I got used to doing .Equals() for comparisons instead of == (at least for cases where I knew / had tested for whether the object I called .Equals() on was not null).
I just ran into a problem with some C#.NET code that had been missed for a few versions because it compiled OK, but at runtime it always returned false, but I'm a bit confused about why it compiled, can somebody please explain? (I'm guessing it maybe has something to do with Equals() being inherited from object, but didn't see a good reference for this).
Story: I had a class I use for filtering database queries, called WorkFilter, and I converted the filter engine to support multi-value filters (as opposed to just single-value filters). So each filter field property of WorkFilter was converted from String to List<String>, and I converted most of the code (except this one case I missed) to deal with this, and it was fine for a while until I noticed that a certain condition was never true.
Filter class looks like this:
public class WorkFilter
{
public List<String> RecordType { get; set; }
public List<String> Product { get; set; }
... etc ...
}
The "bad" code was doing this:
if (workFilterInstance.RecordType != null && workFilterInstance.RecordType.Equals("REQUEST"))
{
// code that never gets fired because List<String> never equals String value
}
I fixed it to do this (basically):
if(workFilterInstance.RecordType != null && workFilterInstance.RecordType.Contains("REQUEST"))
{
// now this can handle logic for RecordType = "REQUEST" filters
}
I was kicking myself because I know that if I had used == instead, it would have failed at compile time, for example, if I did this: RecordType == "REQUEST" because you can't use the equality operator to compare List<String> and String.
But I was surprised by my misunderstanding of .Equals() because I expected RecordType.Equals(String) to also generate a compiler error (or at least a runtime error, instead of always returning false)... I mean, why would you ever compare List<> to String anyway, and why did this compile?
I poked around MSDN a bit but was hoping somebody could explain it in plain english. Thanks!
Because List<T> is an Object and Object provides Equals implementation. Which is defined as:
public virtual bool Equals(
Object obj
)
now since your parameter passed is a string which is again an object, it compiles.
For your comment:
But why would that not fail at runtime? Is there no protection against
doing what I did? –
It will return false. There is no reason for it to fail. (Although IMO, it should show a warning). If you use Resharper you will get a warning:
Suspicious comparison: there is no type in the solution which is
inherited from both
This code compiles because the Equals method of List<T> is an override of the Equals method of System.Object:
public virtual bool Equals(
Object obj
)
It would not fail at runtime because the contract for Equals requires that
x.Equals(y) returns the same value as y.Equals(x).
and System.String's Equals(Object) will return false if it is passed something that is not a string:
true if obj is a String and its value is the same as this instance; otherwise, false.
Yes; it would be nicer if you would get a warning or error for that.
However, the type system is not rich enough to express that.
You want to write
public virtual bool Equals(??? o);
Where ??? means any type convertible to the qualifier on which the method was called.
It should be fairly easy to write a Roslyn diagnostic to catch this.
I have code where I get a string as input, and I compare it with an integer.
I saw that integer variable also has an Equals function that accepts a string parameter.
I have used it directly thinking it will typecast it.
It did not give any compile time or runtime error, but it always gives a false result.
For example,
int sessionId = 1;
string requestId="1"
return sessionId.Equals(requestId);
sessionId.Equals(requestId) always gives false.
Why is the reason for such behavior? If there is a reason, why are they allowing it run without error?
Integers and strings are always different, and thus "1".Equals(1) returns false.
It compiles because object.Equals(object other) takes an object as the right side, and thus accepts any type.
The reason why this happens is that a string "0" is not the same as 0, so it returns false.
Why is such behavior supported? Because the Equals method allows you to pass an object as a parameter, and a string is in an object, so you are "allowed" to do it. As you have found, it's not very useful in this case.
To solve your problem either get a string representation of the integer, or parse your string to an integer, then compare.
E.g. Try
return (sessionId.ToString() == requestId);
or
return (sessionId == int.Parse(requestId));
If you choose the later you may need to consider if the Parse could fail and how you might handle that.
Yes, Equals takes any type on the right side because it is requires an object. But inside the function it requires the same type as the left side. IMHO there's no need to throw an exception for type mismatching because one only wants to know about equality of two types.
Decompiled Equals of int:
public override bool Equals(object obj)
{
return obj is int && this == (int)obj;
}
If someone shows you a car and a banana, and asks whether they are the same thing, would you throw a temper tantrum because a car is a vehicle and a banana is a fruit, or would you simply say "no, they are not the same thing"?
In many languages, trying to compare an integer and a string will yield a compiler error, because the compiler knows that the integer and the string cannot possibly be the same thing and thus any code that tried to compare them would almost certainly be erroneous. On the other hand, when you say sessionId.Equals(requestId), the compiler knows that you are asking that requestId be passed to the Int32 override of Equals. Since that override can accept a reference to any kind of heap object, it has no problem passing the string "1". That method in turn knows that it was given something which isn't the same as an Int32 with the value 1. It doesn't know that the calling code can't possibly supply anything that would match an Int32; all it knows is that the particular value isn't the same, and because the value isn't the same it perfectly happily returns false.
Shouldn’t we be using String.Compare for string comparison and forget about Equals?
I did have the same problem and I believe the function Equals should throw an exception. In my case, I have been comparing a string with a Boolean.
The discussion by now went wrong way. This is my view:
If a comparison between objects belonging to two different classes always returns false, then they do not need to be compared in the first place.
If there is a need to have a function that bypasses type checking, there should be one. However, having the function Equals positioned as a recommended method for string comparison and in the same time introducing the possibility of unneeded bugs (which may sit in your program for eternity) is a kind of irresponsible.
Moreover, it is extremely misleading that the function call String.Equals(string1, string2, StringComparison. xxx) also accepts non-string arguments. Thus not only string1.Equals(string2).
If that is by design, then it is a poor design.
I could write the following to convert an object to an integer.
Convert.ToInt32(myObject);
But I could also write
Int.Parse(myObject.ToString());
Is there any difference?
Which one should I be using?
Thanks in advance.
Is there any difference?
Yes, Int32.parse(myObject.ToString()); takes a detour to string, that will usually work but it is unnecessary and it might fail or give a different result.
Which one should I be using?
In general, Convert.ToInt32(myObject);
But it depends on what type of data you want to convert.
If myObject = '1'; , do you want 1 or 49 ?
If myObject = false; , do you want 0 or an exception ?
etc
This how Convert.ToInt32 method source looks like
public static int ToInt32(object value) {
return value == null? 0: ((IConvertible)value).ToInt32(null);
}
As long as your object implement IConvertible interface you should call this method.
According to the documentation, it would depend on the object and whether or not it implements the IConvertible interface. There are a number of reasons that make these approaches different. Notably, if the string representation doesn't represent the corresponding integer value (e.g., "{ Value = 123 }") or the object isn't IConvertible. I would choose using Convert.ToInt32() as the conversion is defined by the type and not relying on some observed property that could change in the future.
As far as I know, Convert and Parse do differ in so many ways:
To convert means to cast an object from its original type to another type (if possible).However both objects are somehow equal in their own context for example "32" is the string version of 32 (as an integer).In some languages like Visual Basic this kind of conversion can happen implicitly.
To parse means to accept an input (usually in the form of an string) and to translate it to an object which can be a totally different thing. Take date as an example:We can parse "20 July 2010" which is a string to a date. It means that we have to translate the provided string into a date object that has 20 as its day,7 as its month and 2010 as it year. It is obvious that this task is not a straightforward one and a logic should be in place to parse the string.
This is a Java and C# question.
We all know that, Object Identity(==) tests whether two objects refer to the same location and Obejct Equality(Equals method) tests whether two different (non identical)objects have the same value .But In case of string object Object Identity and Object Equality are same.
For e.g Below two boolean expressions in if statements return true
string a="123";
string b="123";
if(a==b)
if(a.Equals(b))
Why is it so??
What is the rational behind this design decision?
Java and C# both use a memory-saving technique called string interning. Because strings are immutable in these languages, they can pool frequently-used strings (included hard-coded string literals, like in your example) and use multiple references to that one string in memory to save space.
As far as I know, in .net the == Operator for Strings is overloaded to use Equals() instead of object identity. See this explanation for details: http://www.dotnetperls.com/string-equals
For if you need to know if it's really the same object, use this:
Object.ReferenceEquals(string1, string2)
Actually, at least in Java, there is a caching mechanism on strings. A pitfall is that two strings that are equal will sometimes, but not always return true when applying the identity operator. the following code prints false:
String a="123";
String b="12";
b=b+"3";
System.out.println(a==b);
If you really want to make sure, that a.equals(b) == true but (a==b) == false evaluates to false for two String a and b, then you can use the completely undervalued (^^) String constructor:
String a = new String("abc");
String b = new String("abc");
if (a.equals(b)) {
doTheyAreEqual();
if (a != b) {
doButNotTheSame();
}
}