What is the shorthand equivalent to the following snippent of code?
if (strValue == ""){
throw new Exception("Mandatory 'strValue' parameter empty");
}
It's probably as short as you can get it, barring removal of spaces and braces (and sacrificing readability in the process).
As for correctness... this might be better:
.NET 4.0:
if (string.IsNullOrWhiteSpace(strValue)){
throw new ArgumentException("Mandatory 'strValue' parameter empty");
}
.NET < 4.0:
if (string.IsNullOrEmpty(strValue)){
throw new ArgumentException("Mandatory 'strValue' parameter empty");
}
Also note that it is bad practice to simply throw Exception - it is much better to select an appropriate exception class from the BCL if one exists, or a custom one if one doesn't. (thanks #djacobson)
if(strValue=="")throw new Exception("Mandatory 'strValue' parameter empty");
All you can do is remove the braces and spaces :)
With a null check, which I think you want, and using ArgumentException:
ThrowIfNullOrEmpty(strValue, "strValue");
...
private void ThrowIfNullOrEmpty(string parameterValue, string parameterName)
{
if String.IsNullorEmpty(parameterValue)
{
throw new ArgumentException("Mandatory 'strValue' parameter empty",
parameterName);
}
}
Obviously only useful if you're doing this more than a few times.
You could use Code Contracts.
You could also use string.IsNullOrWhitespace()
Contract.Requires(string.IsNullOrEmpty(strValue), "** fancy localized message here ***");
It's already short. Instead of doing strValue == "", I'd do String.Empty or String.NullOrEmpty, I can't remember which one is available in .NET
Does not get much shorter, but if want less lines then:
if (String.IsNullOrWhitespace(strValue)) throw new Exception("Mandatory 'strValue' parameter empty");
You're pretty much as short as you can get. I recommend using the IsNullOrEmpty String function for checking for an empty string. Also, it may be suitable to be more specific in your exception handling and throw an ArgumentException.
if (String.IsNullOrEmpty(strValue)) { throw new ArgumentException("strValue must not be null or empty") };
Assuming that you're trying to write more defensive code, you could use Trace.Assert
Trace.Assert(strValue != "", "Mandatory 'strValue' parameter is not empty");
Or you could use the Fluent Validation library to encapsulate more complicated validation.
Related
In C# 6.0, string interpolations are added.
string myString = $"Value is {someValue}";
How are null values handled in the above example? (if someValue is null)
EDIT:
Just to clarify, I have tested and am aware that it didn't fail, the question was opened to identify whether there are any cases to be aware of, where I'd have to check for nulls before using string interpolation.
That's just the same as string.Format("Value is {0}", someValue) which will check for a null reference and replace it with an empty string. It will however throw an exception if you actually pass null like this string.Format("Value is {0}", null). However in the case of $"Value is {null}" that null is set to an argument first and will not throw.
From TryRoslyn, it's decompiled as;
string arg = null;
string.Format("Value is {0}", arg);
and String.Format will use empty string for null values. In The Format method in brief section;
If the value of the argument is null, the format item is replaced with
String.Empty.
It seems that the behavior depends on which underlying formatting methods are called, and the implementation of these can change over time. If you get a null formated into the string such as "(null)", it is not sure this will stay the same over several years. In some newer version of .NET it can start throwing an exception.
So I think the most safe approach is to make some condition to avoid using the null. Write a simple ternary operation like:
int? someValue = 5;
var valueStr = (someValue is not null) ? someValue.ToString() : string.Empty;
var myString = $"Value is {valueStr}";
It is an extra line of code, but at least the behavior is controlled.
I was reading this blog post by Eric Lippert http://ericlippert.com/2013/06/17/string-concatenation-behind-the-scenes-part-one/#more-1228 and became aware that the empty string is not an identity of concatenation in C#. I haven't run into a situation that made me aware this was the case and always just assumed it was an identity. I assume there is some good reason why
string NullString = null;
NullString = NullString + String.Empty; // results in and empty string, not null
results in an empty string rather than null, what is that reason? Why is there no identity of string concatenation? Was it made that way for convenience or practicality?
The documentation for String.Concat explains this behavior:
An Empty string is used in place of any null argument.
Basically, the String.Concat method was designed to exhibit this behavior.
Was it made that way for convenience or practicality?
While only the framework design team could directly answer this, this behavior does has some practical benefits. This behavior allows you to concatenate strings with null and not create null results, which reduces the number of explicit null checks required in most code. Without this behavior, someString + "abc" would require null checking, wheras with it, a non-null value is guaranteed.
I must admit that i don't understand "the identity of string concatenation". However, the reason why null + string.Empty is not null but string.Empty is:
because it was implemented in this way.
Have a look:
public static string Concat(string str0, string str1)
{
if (string.IsNullOrEmpty(str0))
{
if (string.IsNullOrEmpty(str1))
{
return string.Empty;
}
return str1;
}
else
{
if (string.IsNullOrEmpty(str1))
{
return str0;
}
int length = str0.Length;
string text = string.FastAllocateString(length + str1.Length);
string.FillStringChecked(text, 0, str0);
string.FillStringChecked(text, length, str1);
return text;
}
}
This is also documented:
The method concatenates str0 and str1; it does not add any delimiters.
An Empty string is used in place of any null argument.
If you ask for the why. I assume because it's safer this way. If you want to concat two strings and one of both is null, why should null be favored instead of string.Empty?
Because it uses a contract, the purpose of which is described at Code Contracts.
From String.Concat:
Contract.Ensures(Contract.Result<string>() != null);
Note that NullString + NullString also returns an empty string.
I recently bumped into an exception in my code because I was trimming a null string.
I replaced it with the following:
SomeValue = (SomeString ?? "").Trim();
Can this code ever fail?
Thanks.
Note: I know I can add a try/catch; I'm just looking to make this line fail-proof without using a try/catch.
This will not fail (ie. throw a NullReferenceException), assuming SomeString is indeed a string.
You could achieve the same in many ways:
SomeValue = (SomeString == null)?string.Empty:SomeString.Trim();
It's not the way I would have done it, but no, this shouldn't ever fail now.
I'd probably write an extension method that calls trim after checking for null. Something like this:
public static string NullTrim(this String str) {
if(str == null) {
return string.Empty;
}
return str.Trim();
}
This allows all of the following to compile and execute without error:
"".NullTrim();
" test ".NullTrim();
((string)null).NullTrim();
Well if it was failing because of NullReferenceException, then now it will definitely not fail because of that. As for the rest, I cannot say without context.
I would like to do something like the below but throw an exception because there is no match. Is that possible?
var val = Regex.Match("nomatchplz", "notgoingtomatch(.*)").Groups[1].Value;
The Regex.Match function returns a Match object. It has the functionality you're looking for. But you should throw the exception yourself
Match x = Regex.Match("","");
if (!x.Success)
{
throw new Exception("My message");
}
Doesn't .Value already throw a NullReferenceException because Group[1] is false? Or is Group[1] already cause an ArgumentOutOfRangeException because the Indexer can't be resolved?
The easiest way is to check the result of the regex and throw if no matches are found. Unless I'm misunderstanding?
I'm using this library to hook keys and I have some problems with comparing e.KeyCode.ToString() with same string.
I have variable which is string equivalent of
Keys.Oemtilde ->
Program.KeyboardTradeHotkey = "Oemtilde";
I keep it in string because I read that string from xml file and I can't seem to get any way to convert string to Keys.
If i use it this way:
if (e.KeyCode.Equals(Keys.Oemtilde)) {
Logging.AddToLog("[Keyboard][Check] " + e.KeyCode);
} else {
// failed to catch - executes else
Logging.AddToLog("[Keyboard][PRESS]");
}
It works fine and: Logging.AddToLog("[Keyboard][Check] " + e.KeyCode); is executed.
If i use it:
if (e.KeyCode.ToString() == Program.KeyboardTradeHotkey) {
Logging.AddToLog("[Keyboard][Check] " + e.KeyCode);
} else {
// failed to catch - executes else
Logging.AddToLog("[Keyboard][PRESS]");
}
It executes else clause. It seems like String Compare doesn't really works in this case even thou both string (e.KeyCode.ToString() and Program.KeyboardTradeHotkey are the same.
What can be the reason for this?
another change make use of string.Equals function to compare string
string1.Equals(string2)
I think it is because KeyCode.ToString() doesn't return what you expect it to return. Look at the view in a Watch.
Without having to look at the library that you are using the first (working) code sample looks like it is comparing enum values, so it is returning a number instead of a string.
The difference between == and .Equals() is because of the differences between reference types and value types. This link gives examples of the different results: Comparison of == and .Equals()
I also agree with pranay_stacker.