I thought that "bill" + "john" + null == billjohn, but in this example of mine it seems to be evaluating to null:
var clients = from client in taxPortalService.Client()
select new ClientViewModel
{
ResidentialAddressLine1 = client.RESADDRESSLINE1,
ResidentialAddressLine2 = client.RESADDRESSLINE2,
ResidentialAddressLine3 = client.RESADDRESSLINE3,
ResidentialAddressLine4 = client.RESADDRESSLINE4,
ResidentialPostalCode = client.RESPOSTCODE,
ResidentialCountry = client.RESCOUNTRY,
IAResidentialAddress = client.RESADDRESSLINE1 + ", " + client.RESADDRESSLINE2 + ", " + client.RESADDRESSLINE3 + ", " + client.RESADDRESSLINE4 + ", " + client.RESPOSTCODE + ", " + client.RESCOUNTRY
};
Am I missing something obvious here?
I'm guessing this is using LINQ-to-SQL or EF as a backend, and it is generating SQL. Well, in TSQL a null concatenated with anything is (by default): null. Perhaps try:
(row.Foo ?? "") + ", " + (row.Bar ?? "") + ...
or easier: get the data as values into memory first, then do compositions.
In C#, or rather in .NET, you're right, "bill" + "john" + null gives you "billjohn".
In SQL, 'bill' + 'john' + null gives you null.
Using LINQ to Entities translates your C# to SQL, and subtle differences such as this aren't always preserved.
You can use the more verbose
(client.RESADDRESSLINE1 ?? "") + ", " + (client.RESADDRESSLINE2 ?? "") + ", " + ...
to make sure you only concatenate non-null strings, which won't have this problem.
Assuming SQL-Server as rdbms, a quick test reveals:
select 'A' + NULL; // NULL
Demo
MSDN
The + (String Concatenation) operator behaves differently when it
works with an empty, zero-length string than when it works with NULL,
or unknown values. A zero-length character string can be specified as
two single quotation marks without any characters inside the quotation
marks. A zero-length binary string can be specified as 0x without any
byte values specified in the hexadecimal constant. Concatenating a
zero-length string always concatenates the two specified strings. When
you work with strings with a null value, the result of the
concatenation depends on the session settings. Just like arithmetic
operations that are performed on null values, when a null value is
added to a known value the result is typically an unknown value, a
string concatenation operation that is performed with a null value
should also produce a null result. However, you can change this
behavior by changing the setting of CONCAT_NULL_YIELDS_NULL for the
current session. For more information, see SET CONCAT_NULL_YIELDS_NULL
(Transact-SQL). If the result of the concatenation of strings exceeds
the limit of 8,000 bytes, the result is truncated. However, if at
least one of the strings concatenated is a large value type,
truncation does not occur.
Related
I'm trying to do some Selects in a Datatable, but I am having some problems because I have values in some cells like this: 'COX-12-3SCS4CSCH
This value has ' and -
I tried to do this select but doesn't work:
string expression = "Nivel='" + lvfin + "' AND [Nivel " + lvfin + "]='" + codActual + "'";
DataRow[] results = DataTable.Select(expression);
lvfin contains for example 0 and codActual contains 'COX-12-3SCS4CSCH
And I get this error:
Missing operand after operator 'COX'
What is the problem here?
If your field name is Nivel 0 then you need to add that zero to the constant string "Nivel" and enclose the whole field name into square brackets to form the correct field name used in the first condition, then, if the value that you search contains a single quote, then you need to double it. All this is necessary to avoid confusing the parser when you use a single quote as delimiter for string values or your field names contains spaces.
So you should write (line by line for clarity but could be written in a single line):
string fieldName = "Nivel " + lvfin.ToString();
string searchValue = codActual.Replace("'", "''");
string expression = $"[{fieldName}]='{searchValue}'";
DataRow[] results = DataTable.Select(expression);
I am trying to remove the last 6 characters from item.Size because the data has a decimal place and 5 trailing 0s in the database.
sb.Append("<div>" + item.Size + " " + item.Units + " </div>");
ie. item.Size is displayed as 1.00000 and I need it to just be displayed as 1.
This is part of a StringBuilder, and as I'm new to coding, not even sure the right way to go about this.
sb.Append("<div>" + (int)item.Size + " " + item.Units + " </div>");
StringBuilder has the same formatting capabilities as String.Format when you use the AppendFormat method:
sb.AppendFormat("<div>{0:N0} {1} </div>", item.Size, item.Units);
The format string "N0" tells it to format the number with 0 decimal points. That assumes the item.Size is stored as a numerical type. If not, simply remove the part of the string you don't want:
sb.AppendFormat("<div>{0} {1}</div>", item.Size.Split('.')[0], item.Units);
Here I've used Split, assuming that the value is actually something like what you've shown in your example.
Better you use int.TryParse(or Int32.TryParse) method. because if item.Size is not convertible to int, then it wont give you any exception. you can use int or long according to your choice. So you can handle this in your code according to the if/else condition.
Sample Code:
int size;
string str = "";
if(int.TryParse(str, out size) == true)
{
}
else
{
}
Ive read a few posts on here and the common suggestion is that stringbuilder is the most efficent if joining over three strings.
all variables are other properties.
public string Summary
{
get
{
return Name.Replace("_", " ") + "<strong>[" + Total + " Devices - " + BadCount + " Offline, " + PendingCount + " Pending]</strong>";
}
}
Im joining four, is a simple concatenation suitable or should I ue stringbuilder? Just seems a little overkill.
Use whatever is most readable in this case. Otherwise it's premature optimization.
I would use String.Format:
String result = String.Format("{0}<strong>[{1} Devices - {2} Offline, {3} Pending]</strong>"
, Name.Replace("_", " ")
, Total
, BadCount
, PendingCount);
return result;
Even string concatenation is not that bad since strings are stored in the intern pool. So if you use a string a second time it's not created but the already available reference is used.
So as rule of thumb:
If you're concatenating few strings and the code gets hardly to understand, use String.Format
If you're concatenating few (literal) strings and the code is still readable, use +(string concatenation)
If you're creating strings in a (long) loop with variable strings, use a StringBuilder
Use String.Format
public string Summary
{
get
{
return String.Format(
"{0}<strong>[{1} Devices - {2} Offline, {3} Pending </strong>",
Name.Replace("_", " "), Total, BadCount, PendingCount);
}
}
I'm creating a query string in a web form, and I'm dealing with values from the parameters that might be null. There are lots of ways to check and fix these, but the most elegant one I found is the following:
string pass;
pass = "BillabilityDetail.aspx?_startDate=" + _startDate.Text + "&_endDate=" + _endDate.Text +
"&_isContractor=" + _isContractor.SelectedValue + "&_busUnit=" + _busUnit.Text
+ "&_projectUnit=" + _projectUnit.SelectedValue + "&_leadCon=" + _leadCon.Value ?? -1
+ "&_acctExec=" + _acctExec.Value ?? -1 + "&_isBillable=" + _isBillable.SelectedValue +
"&_isActive=" + _isActive.SelectedValue + "&_include=" + _include.SelectedValue;
The only issue is... it doesn't work. When the code reaches this part,
"&_leadCon=" + _leadCon.Value ?? -1 + "&_acctExec=" + _acctExec.Value ?? -1
the string stops assigning values. So the string would end with &_leadCon=.
I know of ways to work around this, but I don't know why it stopped working in the first place. Any tips?
The + has higher precedence than ??, thus you need to surround your null-coalescing expressions in parenthesis.
"&_leadCon=" + (_leadCon.Value ?? -1) + "&_acctExec=" + (_acctExec.Value ?? -1 )
See the precedence chart here
Try using parentheses to tell the compiler exactly what you mean.
For example:
"&_leadCon=" + (_leadCon.Value ?? -1) + "&_acctExec=" + (_acctExec.Value ?? -1)
You need to add braces i.e.
"&_leadCon=" + (_leadCon.Value ?? -1) + "&_acctExec=" + (_acctExec.Value ?? -1)
If you look at the precedence of operators in C# (more up to date but slightly less helpful version here), then you can see + comes above ??.
This means you are actually asking for most of your statement after ?? to be treated as one block.
So,
string test = "hello" + value ?? "this is" + " a test"
actually means:
Add "hello", then add "this is" + " a test" if value is null, otherwise add value itself.
So you probably want brackets in there as other answers said. I just thought I'd try and explain it a bit more.
There are more issues than you think:
As you said, it does not work
There are about 20 string creations (srting is immutable, string + string creates a new string and copies the contents of strings into it, so it's lot of memory copying). Hovewer, C# compiler makes an optimization for you, so this time you are lucky.
It barely readable
Consider using String.Format method.
string urlTemplate = 'BillabilityDetail.aspx?_startDate={0}&_endDate={1}';
pass = String.Format(urlTemplatel, _startDate.Text, _endDate.Text);
Also, as others pointed out, there are operator preceence errors (+ has higher precedence than ??), but this approach is free of it, as those coalescing operators will reside in parameter construction.
I have a textbox1 two and three. In textbox1 number zero, in two number one and in three number two and use this code
textBox4.Text = "" +
(int.Parse(textBox1.Text) +
(int.Parse(textBox2.Text +
(int.Parse(textBox3.Text)))));
but result is 012..you can have the entire amount, 3?
int result =
int.Parse(textBox1.Text) +
int.Parse(textBox2.Text) +
int.Parse(textBox3.Text);
textBox4.Text = result.ToString();
Try this
What's happening here is that the sum is being evaluated from left to right and this is causing a different type of addition to be performed than what you would expect. In C#, you can add two strings. If you add "foo" to "bar" then this will give you the string "foobar". If you add a string and a number together, then it will convert the number to a string and add the two strings together. So "foo"+13 yields "foo13".
So what's happening in your example is quite complicated. Starting from the inside, you have: int.Parse(textBox3.Text). This takes textBox3.Text which is "2" and converts it to the number 2. Next you do textBox2.Text + (int.Parse(textBox3.Text) which gets the string "1" and then adds the number 2 to it. This causes the number 2 to be converted to the string "2" and then adds "1"+"2", giving the string "12" as the answer since strings are added by joining them. Next you do int.Parse(textBox2.Text + (int.Parse(textBox3.Text)) which converts the string "12" to the number 12. You also do int.Parse(textBox1.Text) which gives the number 0. So at this point you're adding "" + 0 + 12. It does this from left to right, first adding "" to 0. This causes 0 to be converted to "0" and "" + "0" gives "0". Then we are adding "0" + 12. When we do this, 12 gets converted to "12" and "0"+"12" gives "012".
Without making big changes, you could get the correct result just by changing your parentheses. If the numbers were all added together before any of them are added to strings, then you'll get the correct result. We can accomplish this with parentheses.
textBox4 = "" + (int.Parse(textBox1.Text) + int.Parse(textBox2.Text) + int.Parse(textBox3.Text));
In short, it's really important to pay attention to what's happening in what order and what the types are because adding two strings is completely different from adding two numbers.
Put the " mark at the end that way it does the regular math first, then the string conversion.
You can you smth like this:
int sum=int.Parse(textBox1.Text) + int.Parse(textBox2.Text) + int.Parse(textBox3.Text);
textBox4.Text = String.Format("{0}",sum);
You have 2 problems here. The first one is the "" at the beginning. When you do the first +, textBox1.Text is first parsed, then converted to string again by the string concatenating operator. I'd prefer something like this:
textBox4.Text = (int.Parse(textBox1.Text) + int.Parse(textBox2.Text) + int.Parse(textBox3.Text)).ToString();
The second problem (the real one) is the fact that you miss a closing parenthesis after textBox2.Text. In this way you are first concatenating textBox1.Text ("1") and int.Parse(textBox2.Text).ToString() ("2"), and only at this point you parse the result. If the parenthesis were not missing your code would give "3" and not "012"