If I declared a bool isTrue = false; // init it to false
and I can get the value from a string strVal = T; // I assumed it is the TRUE value
I heard it is not a good code style to compare string in C# like
if (isTrue.tostring() == strVal) {}.
Some time, I covert the the string variable to enum then I can compare it more convenient.
Is there any good method to do it?
Yes, you parse the string into a boolean first.
Try this:
bool someBool = false;
string boolVal = "true";
bool stringBool;
bool.TryParse(boolVal, out stringBool);
if (someBool == boolVal)
{
}
Alternatively to handle 'T' and 'F' try these methods:
public bool ParseString(string maybeBool)
{
return ParseString(maybeBool, false);
}
public bool ParseString(string maybeBool, bool def)
{
bool stringBool;
if (bool.TryParse(maybeBool, out stringBool))
return stringBool;
if (string.Equals(maybeBool, "T", StringComparison.OrdinalIgnoreCase))
return true;
if (string.Equals(maybeBool, "F", StringComparison.OrdinalIgnoreCase))
return false;
return def;
}
Try bool.Parse() method instead.
bool.Parse(boolVal) == isTrue
There is no need to convert boolean values to strings in order to compare the two. You can simply compare the two boolean values directly:
if (isTrue == boolVal) {}
Update: (following updated question)
You can parse a string into a boolean and use the resulting boolean in your comparison (as above), using either bool.Parse or bool.TryParse.
you may compare boolean type instead.
bool temp = bool.Parse(strVal);
if(isTrue == temp)
Yet another version which i use a lot is simply Convert.ToBoolean(stringFromBoolVal)
regards
If you really want to do string comparisons:
if (string.Equals(isTrue.ToString(), strValue)) { }
How about trying this simple way to determine the value of bool variable isTrue:
isTrue = strVal == "T";
isTrue will return true if the strVal is equaled to "T". And return false if not.
Related
I am having an issue on my BizTalk application
I have customized the functoid to change value based on the boolean it has received her is the code
public string GetBoolMark(bool param1)
{
string returnValue = "0";
if (param1 == true )
{
returnValue = "1";
}
return returnValue;
}
I am having an issue that the value always returns the true value. I am using BizTalk server 2013 R2
Change the type of param1 from bool to string.
Parse it carefully inside you function to a boolean, and use that boolean to decide what to return.
public string GetBoolMark(string param1)
{
bool condition;
string returnValue = "0";
if (bool.TryParse(param1, out condition) && condition)
{
returnValue = "1";
}
return returnValue;
}
When using the inline C# in a scripting functoid, I always find it easier to assume all parameters are strings.
If you use other type, some implicit parsing will be performed for you. I'd rather perform the parsing myself explicitly because I don't know exactly how the implicit parsing works.
If it is indeed xs:boolean, you can do:
public MyFunctoid(string MyParam)
{
if(MyParam == "true")
{
return "It was true!";
}
return "It was false!";
}
This is because the value of MyParam can be one of only 3 things, 'true', 'false' or ''. You only need to test for 'true'. This is one case where a [Try]Parse is not necessary.
What I currently have:
bool okPress = !string.IsNullOrEmpty(Ctx.Request["okPress"]) &&
Convert.ToBoolean(Ctx.Request["okPress"]);
Correct me if I'm wrong here, but wouldn't this throw a FormatException if the string isn't "true/True" or "false/False"? Is there any way to handle the conversion in one row, without having to worry about exceptions? Or do I need to use Boolean.TryParse?
You can use Boolean.TryParse:
bool okPress;
bool success = Boolean.TryParse(Ctx.Request["okPress"]), out okPress);
For what it's worth, here a "one-liner", create following extension which might be useful especially in LINQ queries:
public static bool TryGetBool(this string item)
{
bool b;
Boolean.TryParse(item, out b);
return b;
}
and write:
bool okPress = Ctx.Request["okPress"].TryGetBool();
IF you didn't want to use TryParse You could do something like
bool okPress = !string.IsNullOrEmpty(Ctx.Request["okPress"]) &&
(Ctx.Request["okPress"].ToLower()=="true");
This way if the string is not true/false it will just assume false for you with no exceptions thrown.
This does of course assume that you are happy for a value of "fish" to be treated as false rather than as an exception.
Better though is to just not do it as a single line. You don't generally have a maximum number of lines of code so two or three simple lines of code are often better than one complicated line of code...
Why don't you compare the string against true?
bool okPress = !string.IsNullOrEmpty(Ctx.Request["okPress"]) &&
String.Compare(Ctx.Request["okPress"], "true", StringComparison.OrdinalIgnoreCase) == 0
You can use TryParse method of Boolean class as you said.
Tries to convert the specified string representation of a logical
value to its Boolean equivalent. A return value indicates whether the
conversion succeeded or failed.
bool result = Boolean.TryParse(Ctx.Request["okPress"]), out okPress);
It returns true if value was converted successfully; otherwise, false.
Your inline conversion.
public static bool TryParseAsBoolean(this string expression)
{
bool booleanValue;
bool.TryParse(expression, out booleanValue);
return booleanValue;
}
bool okPress = Ctx.Request["okPress"].TryParseAsBoolean();
My question is not about how to solve this error(I already solved it) but why is this error with boolean value.
My function is
private string NumberToString(int number, bool flag)
{
string str;
switch(flag)
{
case true:
str = number.ToString("00");
break;
case false:
str = number.ToString("0000");
break;
}
return str;
}
Error is Use of unassigned local variable 'str'. Bool can only take true or false. So it will populate str in either case. Then why this error?
Moreover this error is gone if along with true and false case I add a default case, but still what can a bool hold apart from true and false?
Why this strange behaviour with bool variable?
Writing a switch statement on a boolean variable seems kinda wasty to me. Why not use the conditional operator (?:):
private string NumberToString(int number, bool flag)
{
return flag ? number.ToString("00") : number.ToString("0000");
}
The code seems a bit more concise and you don't need local variables.
But back to your question about why your code doesn't compile => it is because variables must always be assigned and this assignment should not happen inside conditional statements.
The error you get is about string variable and not boolean possible values.
The fact that there is no way that noone of cases run, is a true (in this case), but compiler doesn't go so far in analyzing the code. It just looks on variable that is not assigned and used in some conditions and there is not default one, so suppose that there could be some case when it remains unassigned.
I think, you are trying to ask, why str variable is unassigned, as the switch statement's cases will assign it some value, but the compiler can't determine whether it will fall in any of the case statement, That is why you are getting this error on returning str.
If you add a default case with string assignment, then the compiler will know for sure that, the str will hold some value and that is why you don't get error
private string NumberToString(int number, bool flag)
{
string str = "";
switch(flag)
{
case true:
str = number.ToString("00");
break;
case false:
str = number.ToString("0000");
break;
}
return str;
}
write this string str = ""; - you should assign value
if you add default case there is no chance to fall through the switch cases without assigning. Now it is
Well, there's been good explanation for causes of this issue, but there is one more solution to the problem, which was not mentioned. Just put default instead of second case:
private string NumberToString(int number, bool flag)
{
string str;
switch (flag)
{
case true:
str = number.ToString("00");
break;
default:
str = number.ToString("0000");
break;
}
return str;
}
It leaves compiler with no further thoughts about flag variable value as we always assign a default value in our switch statement.
Also consider if-else statement equivalent solution:
private string NumberToString(int number, bool flag)
{
string str;
if (flag)
str = number.ToString("00");
else
str = number.ToString("0000");
return str;
}
I am not particularly fond of 'one-liners' (one line solutions), as they lack extendability and moreover - readability, but as the last resort just use ternary operators like this:
private string NumberToString(int number, bool flag)
{
return flag ? number.ToString("00") : number.ToString("0000");
}
While I am at it - consider using extension method + defaulting boolean to false, for example:
public static class intExtensions
{
public static string NumberToString(this int number, bool flag = false)
{
return flag ? number.ToString("00") : number.ToString("0000");
}
}
and then in main class:
int intVal = 56;
string strVal1 = intVal.NumberToString(true);
string strVal2 = intVal.NumberToString();
Why does
Convert.ToBoolean("1")
throw a System.FormatException?
How should I proceed with this conversion?
Yes, this is as documented:
[throws] FormatException [if] value is not equal to TrueString or FalseString.
TrueString is "True" and FalseString is "False".
If you want to detect whether a string is "1" or not, use this code:
bool foo = text == "1";
Depends on what you want. Perhaps
var result = Convert.ToInt32(yourstirng) != 0
assuming any number but 0 is true. Otherwise a simple comparison would work.
var result = yourstirng == "1"
The parameter must be equal to either Boolean.TrueString or Boolean.FalseString. The values of these strings are "True" and "False", respectively. See MSDN.
The string value "1" is obviously not equal to "True" or "False".
The problem is, that youre giving a String here, not a number. It cant convert the String "1" to true, but the int 1.
Convert.ToBoolean(1);
should work.
When converting to Boolean it is best to use your own routine, where you handle all cases. .net Convert.ToBoolean isn't a practical routine, it is one of those function where you have to explain why it doesn't work.
I know this is old, but in case someone searches... simply do this:
Convert.ToBoolean(Convert.ToInt16("1")) works just fine. Not pretty, but needs be.
Another solution is to use an Extension Method on the string object. I used this technique in a case where I had to parse CSV files that had different strings that had to be converted to boolean values depending on their source and format.
public static class StringExtensions
{
public static bool ToBool(this string value,string trueValue)
{
if (value == trueValue)
{
return true;
}
else
{
return false;
}
}
}
This would be called like so...
MyProperty = CsvColumn[6].ToBool("1");
If you want, the truevalue parameter could be a string array if you needed to compare multiple values (like n/a, na, none) and you could add in false values if you want to further restrict it or use nullable types.
I know that the following is case sensitive:
if (StringA == StringB) {
So is there an operator which will compare two strings in an insensitive manner?
Try this:
string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
The best way to compare 2 strings ignoring the case of the letters is to use the String.Equals static method specifying an ordinal ignore case string comparison. This is also the fastest way, much faster than converting the strings to lower or upper case and comparing them after that.
I tested the performance of both approaches and the ordinal ignore case string comparison was more than 9 times faster! It is also more reliable than converting strings to lower or upper case (check out the Turkish i problem). So always use the String.Equals method to compare strings for equality:
String.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);
If you want to perform a culture specific string comparison you can use the following code:
String.Equals(string1, string2, StringComparison.CurrentCultureIgnoreCase);
Please note that the second example uses the the string comparison logic of the current culture, which makes it slower than the "ordinal ignore case" comparison in the first example, so if you don't need any culture specific string comparison logic and you are after maximum performance, use the "ordinal ignore case" comparison.
For more information, read the full story on my blog.
There are a number of properties on the StringComparer static class that return comparers for any type of case-sensitivity you might want:
StringComparer Properties
For instance, you can call
StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)
or
StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)
It's a bit cleaner than the string.Equals or string.Compare overloads that take a StringComparison argument.
System.Collections.CaseInsensitiveComparer
or
System.StringComparer.OrdinalIgnoreCase
string.Equals(StringA, StringB, StringComparison.CurrentCultureIgnoreCase);
or
if (StringA.Equals(StringB, StringComparison.CurrentCultureIgnoreCase)) {
but you need to be sure that StringA is not null. So probably better tu use:
string.Equals(StringA , StringB, StringComparison.CurrentCultureIgnoreCase);
as John suggested
EDIT: corrected the bug
You can use
if (stringA.equals(StringB, StringComparison.CurrentCultureIgnoreCase))
Operator? NO, but I think you can change your culture so that string comparison is not case-sensitive.
// you'll want to change this...
System.Threading.Thread.CurrentThread.CurrentCulture
// and you'll want to custimize this
System.Globalization.CultureInfo.CompareInfo
I'm confident that it will change the way that strings are being compared by the equals operator.
Here an idea to simplify the syntax:
public class IgnoreCase
{
private readonly string _value;
public IgnoreCase(string s)
{
_value = s;
}
protected bool Equals(IgnoreCase other)
{
return this == other;
}
public override bool Equals(object obj)
{
return obj != null &&
(ReferenceEquals(this, obj) || (obj.GetType() == GetType() && this == (IgnoreCase) obj));
}
public override int GetHashCode()
{
return _value?.GetHashCode() ?? 0;
}
public static bool operator ==(IgnoreCase a, IgnoreCase b)
{
return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
public static bool operator !=(IgnoreCase a, IgnoreCase b)
{
return !(a == b);
}
public static implicit operator string(IgnoreCase s)
{
return s._value;
}
public static implicit operator IgnoreCase(string s)
{
return new IgnoreCase(s);
}
}
Usable like:
Console.WriteLine((IgnoreCase) "a" == "b"); // false
Console.WriteLine((IgnoreCase) "abc" == "abC"); // true
Console.WriteLine((IgnoreCase) "Abc" == "aBc"); // true
Console.WriteLine((IgnoreCase) "ABC" == "ABC"); // true
I am so used to typing at the end of these comparison methods: , StringComparison.
So I made an extension.
namespace System
{ public static class StringExtension
{
public static bool Equals(this string thisString, string compareString,
StringComparison stringComparison)
{
return string.Equals(thisString, compareString, stringComparison);
}
}
}
Just note that you will need to check for null on thisString prior to calling the ext.
string.Compare(string1, string2, true)
Others answer are totally valid here, but somehow it takes some time to type StringComparison.OrdinalIgnoreCase and also using String.Compare.
I've coded simple String extension method, where you could specify if comparison is case sensitive or case senseless with boolean - see following answer:
https://stackoverflow.com/a/49208128/2338477
if (StringA.ToUpperInvariant() == StringB.ToUpperInvariant()) {
People report ToUpperInvariant() is faster than ToLowerInvariant().
//You can make it case insensitive by
s1.ToLower() == s2.ToLower();