I am having the following code snippet where I pass a value either True or False through the PropertyValue parameter in the method declaration.
public void SetTaskInstance(String PropertyName, String PropertyValue, int row)
{
bool bValue;
try
{
PropertyName = PropertyName.ToUpper();
switch (PropertyName)
{
case "BYPASSRULESENGINE":
m_tInstance.byPassRulesEngine =
System.Boolean.TryParse(PropertyValue.ToString(), out bValue);
break;
}
Console.WriteLine("Invoking method");
}
}
If I pass True, then True is outputted. However if I pass False, the parameter False is passed through the code but once the break statement is reached and when I hover my mouse over m_tInstance.ByPassRulesEngine, I see that the bool value has become True almost magically. Why is this happening ?
The return value of TryParse indicates if the parse was successful. And of course, the value "false" or "False" is valid, so TryParse would return true. The parsed value itself is written into the out bValue parameter.
Change the line
m_tInstance.byPassRulesEngine = System.Boolean.TryParse(PropertyValue.ToString(), out bValue);
to
bool parseSuccessful = System.Boolean.TryParse(PropertyValue.ToString(), out bValue);
if (parseSuccessful)
{
m_tInstance.byPassRulesEngine = bValue;
}
All TryParse methods behave that way. So read the documentation of TryParse on MSDN here:
http://msdn.microsoft.com/en-us/library/system.boolean.tryparse.aspx
Let me explain why you always receive a true value:
The function System.Boolean.TryParse returns true, if it can successfully do the conversion, from a String to a Boolean.
So in your example it will always be true.
Carsten Schütte has already given the solution code.
Look at msdn
the result of the conversion is stored in Output variable (your bValue)
When this method returns, if the conversion succeeded, contains true
if value is equivalent to Boolean.TrueString or false if value is
equivalent to FalseString. If the conversion failed, contains false.
The conversion fails if value is null or is not equivalent to the
value of either the TrueString or FalseString field.
Related
I have the following code.
using System;
class program
{
static void Main()
{
string StrNumber = "100TG";
int result = 0;
bool IsConversionSuccessful = int.TryParse(StrNumber, out result);
if (IsConversionSuccessful)
{
Console.WriteLine(result);
}
else
{
Console.WriteLine("Invalid");
}
}
}
I know that TryParse method tries to convert StrNumber(100TG) into an integer.
And if it succeeds, it's going to save converted value into a result variable and return true for boolean.
And if it fails, a result value will remain as 0 and it will return false for boolean.
My question is that no matter what kind of boolean value IsConversionSuccessful variable gets, wouldn't "if(IsConversionSuccessful)" get activated? Am I misunderstanding TryParse Method?
If IsConversionSuccessful gets to be false, then the condition if(IsConverstionSuccessful) evaluates to if(false). Hence, the body of that if does not execute.
The TryParse method does not determine the execution of the next line in your program. It simply tells you whether the conversion from string to int was successful or not by returning a boolean value.
The lines following TryParse is up to you.
As you clearly have pointed out,
bool IsConversionSuccessful = int.TryParse(StrNumber, out result);
Will set IsConversionSuccessful to true/false based on how the method parsed the number.
If statements in themself evaluate something and always get a boolean answer, true or false. This is because if statements act like binary branch trees. They work like this:
When you evaluate if(A), which in your case is
if (IsConversionSuccessful)
The processor decides on a path to take and execution after that depends on the decision the processor made. Note that even excluding the else branch, an empty else branch simply points back to the "..." that comes after the if statement.
Is there any way to make an out parameter of a method optional? I have a method that needs several parameters to return null most of the time, but sometimes they will have a value. I am trying to find out if there is a better way to accomplish this than by setting the values to null first, or setting them to null after the if/else. This may be the only way to do it, but it would be nice if there were optional out parameters or something equivalent. Here is the code:
private static void GetInitInfo(string initLine, string ncPointType, out double? relinquishDefault, out bool? ignoreRelinquishDefault, out bool? closedForStart, out bool? adjustDisabled)
{
relinquishDefault = null;
ignoreRelinquishDefault = null;
closedForStart = null;
adjustDisabled = null;
switch (ncPointType)
{
case "MSD":
adjustDisabled = LastToken<bool?>(initLine);
break;
case "BO":
relinquishDefault = SecondToken<double>(initLine);
closedForStart = ThirdToken<bool?>(initLine);
ignoreRelinquishDefault = !ForthToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
case "MSO":
closedForStart = SecondToken<bool?>(initLine);
relinquishDefault = ThirdToken<double>(initLine);
ignoreRelinquishDefault = !ForthToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
case "AD":
relinquishDefault = ThirdToken<double>(initLine);
ignoreRelinquishDefault = false;
break;
case "BD":
relinquishDefault = SecondToken<double>(initLine);
adjustDisabled = LastToken<bool?>(initLine);
ignoreRelinquishDefault = false;
break;
case "AOS":
relinquishDefault = FirstToken<double>(initLine);
ignoreRelinquishDefault = !ThirdToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
}
}
This isn't not allowed according to the C# 4.0 Spec: section 21.1.
A workaround is to overload with another method that does not have out or ref parameters.
I believe this question is asking about having to assign values inside the method with out parameters, and whether there is any way to circumvent that, i.e. by leaving the values unassigned rather than explicitly having to assign them null.
e.g. Do you have to write:
public bool OutMethod(out int? output)
{
output = null;
return true;
}
Or is there a way to do something like:
public bool OutMethod(out int? output)
{
return true;
}
With the same result?
Short answer is no, this can't be avoided. See the documentation for an example which includes assigning null explicitly, and states:
Note that the third argument is assigned to null. This allows methods to return values optionally.
Examples of this can also be found in the .NET framework. e.g. Dictionary<TKey,TValue>'s TryGetValue method:
public bool TryGetValue(TKey key, out TValue value)
{
int num = this.FindEntry(key);
if (num >= 0)
{
value = this.entries[num].value;
return true;
}
value = default(TValue);
return false;
}
Note the explicit assignment to default(TValue)
Use the overload with signature that does not have out parameters:
private static void GetInitInfo(string initLine, string ncPointType)
{
double? relinquishDefault;
bool? ignoreRelinquishDefault;
bool? closedForStart;
bool? adjustDisabled;
GetInitInfo( initLine, ncPointType, out relinquishDefault, out ignoreRelinquishDefault,
out closedForStart, out adjustDisabled);
}
The explanation is quite simple: You can do it. Just assign an out parameter inside the method to the desired value.
Now you can ask yourself, why can't we do that in the method signature? Well, let us have a look at the normal optional value parameters. They are assigned a predefined value if they are not assigned by the caller. So caller knows the value, which will be passed if the parameter is not set explicitly. It has a control of it and it is responsible for that decision.
Since the caller of the method is NOT responsible for the assignment of the out parameter, it makes no sense to offer a default value. The only thing you could achieve, by having a default out parameter value is to let the caller know what one of the possible values of that out parameter would be. But would that make sense? When will this value be used? Under what condition? All this is still hidden from the caller. So there is no real benefit from having an optional out parameter value, apart from having a possiblity to set it inside the signature instead of the method body.
So, having that said, the following would not make much sense:
public bool TrySomething(out string outObject = "default value") { ... }
However, what would be cool is to allow the following method
public bool TrySomething(out string outObject) { ... }
to be invoked as follows:
bool result = TrySomething();
And have that behind the scenes equivalent to:
string dummyWhichWillNeverBeUsed;
bool succeeded = TrySomething(out dummyWhichWillNeverBeUsed);
Unfortunately, that is not allowed.
And of course, as explained in other answers, you can always have overloads without out parameter.
Consider the following method example:
public void MyMethod (string par1, bool par2 = "true", string par3="")
{
}
Now let's say that I call MyMethod and set par3's value to "IamString".
How could I do that without setting par2's value to true or false?
I basically want to leave par2 value to its default.
I'm asking this because in Flash's ActionScript it is possible to do that by using the keyword default so I could call MyMethod ("somestring", default, "IamString") and par2 would be interpreted as true, which is its default value. I wonder if it is possible in C# as well.
public void MyMethod (string par1, bool par2 = "true", string par3=""){}
Myclass.MyMethod(par1:"par1", par3:"par3");
By the way, this won't work: bool par2 = "true"
string par2 = "true"
or
bool par2 = true
Talking about default values, you could also use this to get the default value for a particular type:
default(T)
You can specify this by name the parameter:
instance.MyMethod( "Hello", par3:"bla" );
Have a look here.
And there is another bug:
bool par2 = true
is correct..
This code throwing out an error:
bool status1 = (bool)Cache["cache_req_head"];
bool status2 = (bool)Cache["cache_super"];
bool status3 = (bool)Cache["cache_head"];
This is how the cache variables were set:
if (checkreqhead == true)
{
Cache["cache_req_head"] = true;
}
else if (checksuper == true)
{
Cache["cache_super"] = true;
}
else if (checkhead == true)
{
Cache["cache_head"] = true;
}
Coming from PHP background, this is awkward. The error is:
Object reference not set to an instance of an object
I'm certain it is something really simple, but probably I can't spot it.
THANKS ALL FOR HELPING :)
"Object reference not set to an instance of an object" is c# lingo for "you did something stupid with a null value"
If the Cache is empty you need to check that first
bool status1 = (bool)Cache["cache_req_head"];
should be
bool status1 = false;
if (Cache["cache_req_head"] != null)
{
status1 = (bool)Cache["cache_req_head"];
}
This is an effect of the fact that value types (like bool, int, etc) in c# can not be null. There is a wrapper, Nullable<T> with the shorthand T? that you can use if you want to allow null values for the value types.
You can cast your value to a bool? since that allows for null.
bool? status1 = (bool?)Cache["cache_req_head"];
You can then check status1 == null or status1.HasValue, to get the actual bool value you need to pick it out with status1.Value. If you pick status1.Value while status1 == null you will get a runtime exception like the one you just got.
Actually, the best way to check for whether a value exists or not in Cache is by doing:
//string is used as an example; you should put the type you expect
string variable = Cache["KEY"] as string;
if(variable!=null)
{
// do something
}
The reason why doing if(Cache["KEY"]!=null) myVariable=Cache["Key"]; is unsafe, is because the object stored in Cache["Key"] may be removed from Cache before you get a chance to assign it to myVariable and you end up thinking that myVariable holds a non-null value.
You obviously only setting one of the cache entries at a time. So unless you run the "setter" code 3 times with only 1 variable set to true, then you always going to have nulls returned.
null does not cast into bool because its a value type. Try using bool?
Since Cache[] returns an object, which is null if not set, then you're getting an exception trying to cast null into a bool.
You'd have to check if that key exists first, or you'd have to set each key to "false" as a default.
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.