Specified cast is not valid while accessing column value - c#

I am finding records in datatable. If the record matches then I want to compare value in the datarow and do some operation. Please see my code below for better explanation,
foreach (DataRow row2 in dtTo.Rows)
{
DataRow[] match = dtReturn.Select("Id = " + row2["Id"]);
if (match.Length > 0)
{
if (match[0]["boolInt"] == 1) // Getting error on this line
{
match[0]["NewValues"] = "";
}
}
}
I was getting error on below line
if (match[0]["boolInt"] == 1)
Then resharper suggested me to cast to bool. so I changed above line to
if( (bool) (match[0]["bClosed"] = 1))
But when I run the project I get run time error as "Specified cast is not valid" on above line.
In immediate window I get value as 1 when I type ,
(match[0]["bClosed"]
What should i do to get rid of this error?

According this:
No there wont be null. The field is tinyint
you code should look like this (AFAIR, tinyint in SQL server matches byte in CLR):
if ((byte)(match[0]["boolInt"]) == 1)
{
}
If you know the field type, there's no need to call Convert methods. The faster way is to cast directly to that known type.

You need to convert the value to int. You can do it like this:
if (Convert.ToInt32(match[0]["boolInt"]) == 1)
But if the column contains a value that can't be casted you wil get an error.
A better aproach would be:
int number;
bool result = Int32.TryParse(match[0]["boolInt"], out number);
if (result && number == 1)

Try this:
if ((match[0]["boolInt"] as int?) == 1)
{
match[0]["NewValues"] = "";
}
if value is null or not valid int it won't cause exception, but should be handled anyways.

Related

What does the bracket in this expression mean

I am modifying another developer's code and I don't know what the [0] bracket following the string means in this context, can someone explain to me? My first thought is it is referring to the first column of GridView1 but that isn't the correct way to designate a column is it? BTW the string values in the if statement are 7 digit numbers expressed as strings. The first column is the DataKey column.
if (GridView1.SelectedValue.ToString()[0] != '5' && GridView1.SelectedValue.ToString().Substring(0, 2) != "95")
{
LinkButton1.Visible = false;
LinkButton2.Visible = false;
}
else
{
LinkButton1.Visible = true;
LinkButton2.Visible = true;
}
String Accessing Individual Characters
You can use array notation with an index value to acquire read-only
access to individual characters
if (GridView1.SelectedValue.ToString()[0] != '5' && GridView1.SelectedValue.ToString().Substring(0, 2) != "95")
As noted in the comments, both the below will throw if there are not enough characters
GridView1.SelectedValue.ToString()[0]
GridView1.SelectedValue.ToString().Substring(0, 2)
Also as per DRY calling this twice is redundant and also messy
GridView1.SelectedValue.ToString()
When you can
var something = GridView1.SelectedValue.ToString();
Lastly, normally you would check this for sanity sake, Like
if(!string.IsNullOrEmpty(something) && something.Length >= 2)
if (something[0] != '5' && something.Substring(0, 2) != "95")
Anyway, have fun stringing

Having trouble converting string to int

In my program I have a treeView. In the section that I am working with, the node's displayNames are numerical integer values, but are displayed as strings. I have come to a point in my program where I need to convert and temporarily store these displayNames in an integer variable. I usually use Regex.Match() to do this with no problem, but in this scenario I am getting the compiler error: Cannot implicitly convert type 'string' to 'int'.
This is my code:
//This is the parent node as you may be able to see below
//The children of this node have DisplayNames that are integers
var node = Data.GetAllChildren(x => x.Children).Distinct().ToList().First(x => x.identify == 'B');
//Get # of children -- if children exist
if (node.Children.Count() > 0)
{
for (int i = 0; i < node.Children.Count(); i++)
{
//Error on this line!!**
IntValue = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
}
}
*NOTE: DisplayName.Value is a string
To get from string to int, use int.Parse(string), it returns the int represented by the passed string and throws if the input format is incorrect.
int.Parse(node.Children.ElementAt(i).DisplayName.Value)
You can also use int.TryParse if you don't want the throw. in that case you would use:
int parsedValue;
if (int.TryParse(node.Children.ElementAt(i).DisplayName.Value, out parsedValue))
{
///Do whatever with the int
}
The problem is becuase you're casting from Match to int in this call
IntValue = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
Try something like this:
Match m = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
int value = m.Matches[0] //You'll have to verify this line, I'm going from memory here.

TryParse in if condition

I'm Getting a querystring data in ASP.NET C# and I need both its string value and int.Parse value of it (if it can be parsed). (in the example I'm skipping checking for null values as it has no effect on my question)
value = Request.QueryString["value"];
id = int.TryParse(Request.QueryString["value"], out id)
the code above does what I need but I just got curious if I could write it in one sentence so I tried this:
if (int.TryParse(Request.QueryString["value"], out id))) value=Request.QueryString["value"];
in this case I don't get the string value if it can't be parsed but I will get Its parsed value.
Any suggestions? I don't have a problem with my code I'm just asking out of curiosity that if it can be done in single line of code.
The almost-one-liner version would be
// id and value still need to be defined, of course!
int.TryParse(value = Request.QueryString["value"], out id)
Your code shouldn't work: if id is an int it won't be able to hold the bool coming out from TryParse.
You can this out,
int id;
string value = int.TryParse(Request.QueryString["value"], out id)) ? Request.QueryString["value"] : null;
Inline output variables are supported with C# 7.0 (released back in March '17)
var value = int.TryParse(Request.QueryString["value"], out int id) ? Request.QueryString["value"] : null;
id (output variable) will contain the parsed value or default(int)
No, you do not (want) do assignments in conditionals.
Also, if you're assigning it to value then you should utilize value for efficiency.
value = Request.QueryString["value"];
id = int.TryParse(value, out id)
Lastly, you sure about id? You're assigning it to the boolean return of TryParse, yet assigning the out to it as well. I think your code is incorrect, though you say it is good.
I would assume you mean to do this:
var value = Request.QueryString["value"];
int id = -1;
if(int.TryParse(value, out id))
/* Do work here */
You cant declare it all on one line, but if you have multiple int variables you could delclare them all on one line.
Note: if int.TryParse fails is actually sets the out parameter to 0, with out parameters it needs to be assigned before leaving the method so I guess this is why.
eg:
private void test()
{
int id, id2, id3 = int.MinValue;
string value1 = int.TryParse(Request.QueryString["value1"].ToString(), out id) ? Request.QueryString["value1"].ToString() : null;
string value2 = int.TryParse(Request.QueryString["value2"].ToString(), out id2) ? Request.QueryString["value2"].ToString() : null;
string value3 = int.TryParse(Request.QueryString["value3"].ToString(), out id3) ? Request.QueryString["value3"].ToString() : null;
}
If we change Alex's answer to use out int id we don't even need to declare id in a separate line.
int.TryParse(value = Request.QueryString["value"], out int id);
I like my own personal example for others who may need it with null checking and returning both a string and a conversion. You could move the local string variable out if you needed to.
//Sets nUnitPrice to 0 if the value entered is not a double. If null remains 0.00.
if (dgvQuote[colUnitPrice.Index, nRow].Value != null)
{
var unitPriceSubString = dgvQuote[colUnitPrice.Index, nRow].Value.ToString().Replace("$", "").Trim();//Substring local variables reduce the number of times substringing needs to be called.
nUnitPrice = double.TryParse(unitPriceSubString, out _)
? Convert.ToDouble(unitPriceSubString)
: 0.00;
}

The name does not exist in the current context - grrr

In the following code, no matter what I try, the name strSide "does not exist in the current context", when I place a break point as shown. I want strSide to contain the last character in rawId and then to strip that character so that the value of rawId will convert to an integer. I don't get a compiler error, but do get a runtime error.
When the value of rawId is 8429R, the stripping works, but I cannot get the R assigned to strSide.
foreach (string fieldName in Request.QueryString)
{
rawId = fieldName;
String strSide = Convert.ToString(rawId[rawId.Length - 1]); <-- name does not exist
if (!IsNumeric(rawId)) <--break point set here.
{
rawId = StripRightChar(rawId);
}
Qty = Request.QueryString[fieldName];
int productId = 0;
if (fieldName == "txtReference")
{
strComments = Request.QueryString[fieldName];
}
Might the variable have been "optimized away"? It is not used anywhere after its creation. See this for details: How to prevent C# compiler/CLR from optimizing away unused variables in DEBUG builds?.
Do you need the value stored in strSide?
If not you could try this alternative solution
Update, since you need the value, try this:
var s = "8429L";
var numbers = s.Substring(0, s.IndexOfAny("RLB".ToCharArray()));
var letter = s.Substring(numbers.Length);

How can this be not equal?

My Goal: Extracting one value from an Excel Range, and verify for these cells' value to be the same within this range;
When a cell's value is not the same as the other, I need to return null.
Here's a piece of code:
internal object GetValueFromCells(string start, string end, Formats format) {
// Verifying for empty or null parameters here and throwing accordingly...
try {
Range cells = Excel.get_Range(start, end) as Range;
object value = null;
bool sameValue = false;
foreach(Range cell in cells) {
// This condition block shall execute only once, since 'value' shall not be null afterwards.
if (value == null || value == DBNull.Value)
if (Formats.Formated == format) {
value = cell.Text;
// The following results to be false !?...
sameValue = value == cell.Text; // Shall this not be true?
} else {
value = cell.Value2;
// The following results to be false !?...
sameValue = value == cell.Value2; // Shall this not be true?
}
// This results being always false!?...
// Shall this not be true, I wonder?
sameValue = Formats.Formated == format ? value == cell.Text : value == cell.Value2;
if(!sameValue)
return null;
}
return value;
} catch (Exception ex) {
// Exception handling...
}
}
Reading this code, I would humbly expect a value to be returned when all of the cells in the range have the same value (for instance 334).
However, this methods always returns null (Nothing in Visual Basic)!
Anyone might explain what I'm missing here while this:
value == cell.Value2
always returns false?
Perhaps is it my algorithm that isn't quite right?
EDIT #1
This has solved the problem:
sameValue = Formats.Formatted == format ? cell.Text.Equals(value) : cell.Value2.Equals(value);
I accepted #Jerod Houghtelling's answer as his answer suggests both the ToString() and the Equals() methods to solve the problem.
In addition to it, I dislike having to call the ToString() method, since the value can be numbers, and comparing numbers under a string looks odd to me. So I prefer the Equals() way which I adopted within my solution.
I would like to thank #Sir Gallahad and #Jerod Houghtelling for their good answers. This was the first time I had to face such a situation, and they both helped me better understand what was going on under the hood, plus the others who contributed too through comments.
And thanks to those who upvoted my question. This serves a purpose to demonstrate that I was not so dumb asking! =P Hehehe...
I'm guessing that cell.Value2 is returning a new instance of an object each time you call it. Therefore I would deduce the == is checking to see if both sides of the equation are the same instance of the object. To actually compare the value stored on both side you will have to use the .Equals or convert the values to something that can be compared, for example a string.
sameValue = value.Equals( cell.Value2 );
/* or */
sameValue = value.ToString() == cell.Value2.ToString();
Also I don't see value being set in your example.
Probably the value == cell.Value2 are comparing objects that are from different instances.
Try value.ToString() == cell.Value2.ToString()

Categories

Resources