I have a localzation string which apparently if set to null is causing issues in the view. So my solution was to string it.
_localizer["Controller_Account_ResetPassword_ResetFailed"].ToString();
During code review my co-worker reminded me that .ToString() is not null safe. While its highly unlikely that a localization would be null I guess it could be. He suggested the following.
TempData["Message"] = $"{_localizer["Controller_Account_ResetPassword_ResetFailed"]}";
I have two questions.
Why is $"{var}" null safe and .ToString() is not.
Is there a better way of doing it because his solution seams ugly to me.
First of all, the reason is that it's basically decompiled as
var arg = _localizer["Controller_Account_ResetPassword_ResetFailed"];
string.Format("{0}", arg);
and string.Format does a null check on its arguments and automatically replaces them with string.Empty.
Second of all, this solution is beautiful and string interpolation is an ingenious tool. You should use it :)
EDIT:
I kinda overlooked the fact here string interpolation is used solely to fix the null problem. As some have pointed out that is unnecessary and as much as everyone should love string interpolation something like this:
_localizer["Controller_Account_ResetPassword_ResetFailed"]?.ToString() ?? "";
would be a better choice.
I like to use a ToStringSafe extension method for these kind of scenarios
public static class Extensions
{
public static string ToStringSafe(this object value)
{
// return empty string
if (value == null) {
return String.Empty;
}
return value.ToString();
}
}
You can use the ?? operator to substitute "" if needed:
var something = _localizer["Controller_Account_ResetPassword_ResetFailed"] ?? "";
I wouldn't use $"{value}" notation here. First of all it probably is unneeded, second it does extra work by calling string.Format() which internally creates a StringBuilder object.
It also is by no means clear that the only and actual reason for calling $"{value}" would be to deal with a potential null value, which is 100% clear when you use ??.
As it was stated above the string interpolation is null-safe as it's converted internally to the string.Format. However to answer the second question the information of how you're going to handle rare case with null localization is required. The solution suggested by your colleague is good (I'd only recommend to extract the variable instead of inlining for better readability), but you possibly may want to fall back to the non-localized version of the message instead of getting empty string in case of localization absence or handle the situation in any other way. In that case you'll have to do the explicit null verification possibly inside the _localizer type implementation so that it's always guaranteed to return non-null values or fail.
Related
I will often use this code to compare a string:
if(!string.IsNullOrEmpty(str1) && str1.Equals(str2)){
//they are equal, do my thing
}
This handles the null case first etc.
Is there a cleaner way to do string comparison, perhaps with a single method call that will handle possible null values? I simply want to know that the strings are not equal if the testing value is null.
(I'm having dejavu that I may have asked this before, I apologize if so)
Update: In my case, the str2 is a known good string to compare to, so I don't need to check it for null. str1 is the "unknown" string which may be null, so I want to say "str1 does not equal str2" in the cases where str1 is null...
Unlike Java, C# strings override the == operator:
if (str1 == str2)
If you want a case-insensitive comparison:
if (string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase))
If you do not want to treat two null strings as equal to each other, your code is optimal.
If, on the other hand, you want to treat null values as equal to each other, you can use
object.Equals(str1, str2)
for a more "symmetric" approach that also handles null values.
This is not the only approach to a symmetric check of string equality that treats null strings as equal: you could also use string.Equals(str1, str2) or even str1 == str2, which redirects to string.Equals.
I know this is some years old and I think the solution from dasblinkenlight is functionally perfect for what you asked for.
However I do prefer this code for readability reasons:
String.Equals(str1, str2)
There is no built in way to do this, but you could create an extension method to encapsulate this.
public static StringExtensions
{
public static Boolean IsNotNullAndEquals(this string str1, string str2)
{
return !string.IsNullOrEmpty(str1) && str1.Equals(str2)
}
}
then use it like this:
str1.IsNotNullAndEquals(str2);
Naming is going to be your hardest thing here IMO...since you need to convey that you are only null checking str1. When used as an extension method, it reads fairly well, but if used as a regular static, then it doesn't convey that as well.
You can use this code
object.Equals(str1, str2)
This will do it:
string.IsNullOrWhiteSpace(str1) ? string.IsNullOrWhiteSpace(str2) : str1.Equals(str2, StringComparison.OrdinalIgnoreCase);
I know this has been answer while ago and there's good answers, although as per Microsoft documentation (https://learn.microsoft.com/en-us/dotnet/api/system.string.equals?view=net-5.0) you can use the following to check both cases:
if(string.Equals(str1,str2)){
//they are equal with null handling
}
In more recent C# versions, we also have the null coalescing option now. This isn't an exact solution but can be a cleaner one for some purposes. It takes some liberties with "upgrading" str1 to an empty string for comparison purposes, in the instances where it actually is a null.
if((str1??"").Equals(str2))
{
//they are equal, do things here
}
I am aware that I can set null like
string val = null;
But I am wondering the other ways I can set it to null. Is there a funcion like String.null that I can use.
I think you are looking far String.Empty
string val = String.Empty;
Update:
TheFuzzyGiggler comments are worth mentioning:
It's much better to set a string to empty rather than null. To avoid
exceptions later. If you have to read and write a lot of strings
you'll have null value exceptions all over the place. Or you'll have a
ton of if(!string.isNullorEmpty(string)) which get annoying
You can also use the default keyword.
string val = default(string);
Here is another SO question regarding the default keyword:
What is the use of `default` keyword in C#?
null is not a special string value (there's String.Empty for ""), but a general object literal for the empty reference.
Obviously one more way to set something to null is to assign result of function that returns null:
string SomeFunctionThatReturnsNullString() {return null;}
string val = SomeFunctionThatReturnsNullString();
assign it to this value will make it a null ,(chose the right sql datatype , here its double )
System.Data.SqlTypes.SqlDouble.Null
Depending on your application you could use string.Empty. I'm always leery of initializing to null as the garbage collector is great, but not perfect, and could mark your string for garbage collection if used in some way that the garbage collector can't detect (this is very unlikely though).
So here is standard code for IValueConverter
{
if (value == null)
return null;
if (value.Equals(true))
return Colors.Red;
return null;
}
And another way:
{
if (true.Equals(value))
return Colors.Red;
return null;
}
So, by using true.Equals() we are saving a null check. What are general approach and best practices in regards to using true.Equals() or "Hello".Equals() type checks?
P. S. My question is: what is your/general opinion on this: bad/hacky or ok/nice?
The .Equals method generally checks for null anyway, but if you're trying to optimize your code by removing a single null check, you're really missing the mark. This is not going to make a difference in virtually any application.
I have a strong preference for shorter code (and by that I mean less tokens, not using undecipherable short identifiers) - it is often more readable and understandable, less bug prone, and gives you less code to maintain.
So leaving the null check to .Equals by using true.Equals is a clear win in my book.
In this particular example, you could even remove the duplicate return and do
return true.Equals(value) ? Colors.RedColors.Red : null;
but some might find that less readable than the if statement.
First of all you should be probably using base generic class for converters, which has a virtual strongly typed method, in which case you aren't dealing with object, but instead with a bool inside your converter code.
If we are stuck with object value I am advocate of readable and maintanable code and short functions which replace ifs which can become obscure in future.
So id be using smth like
{
if(IsValueBoolAndTrue(value){
return ErrorColor;
}
else {
return DefaultColor;
}
}
Color.Red and null are constants which make their intent unclear too. Also having those 2 constants defined can help with converting back in second method of IValueConverter
Although method IsValueBoolAndTrue technically does same thing as true.Equals(value) does (inside itself it can call this actually), having a special method will help person, who looks at this in future, not to make a "refactoring" which will break code, because he would look at true.Equals(value) with no comments and think that its actually not smth that is suitable or will think that its inelegant code and refactor it, without leaving its funcionality the same.
You can avoid NullReferenceException and "funny" calls like true.Equals(value) by using the static Object.Equals method. Because the method is implement by Object it is available in all methods and it will perform the necessary null checks for you:
return Equals(value, true) ? (Object) Color.Red : null;
or if you dislike the ternary operator:
if (Equals(value, true))
return Color.Red;
return null;
what are the best practices for type conversions in C# ?
int temp=System.ConvertToInt32(Request.QueryString["Id"]);
if (temp!=null)
{ // logic goes here }
This fails if Id somehow turns out to be 'abc'
Please advice the use of of ternary operators and other single line statements apart from if else statements (like using single line ternary operators). Also, do you guys prefer TryParse over Convert & why so ? Have your say fellows.
TryParse has the obvious advantage that in the case of failure it will return false instead of throwing an exception.
The standard pattern would be something like:
int value;
if (int.TryParse(Request.QueryString["Id"], out value))
{
// Use value
}
else
{
// Do whatever you want on failure
}
Now, it's also worth bearing in mind that you can give int.TryParse an IFormatProvider and a NumberStyles - for example, you may well want to specify CultureInfo.InvariantCulture as the IFormatProvider if this is really meant to be an auto-generated ID (rather than one entered by a user).
If you want to effectively have "default values" you could write a helper method like this:
public static int? NullableTryParseInt32(string text)
{
int value;
return int.TryParse(text, out value) ? value : (int?) null;
}
You can then use this like so:
int value = NullableTryParseInt32(text) ?? 10;
Or you could just write a method which takes a default value, of course :)
When it comes to solving any problem that has several similar solutions I also try to find the one that express to the reader of the code what I'm trying to accomplish the cleæret. In my oppinion that means going for the .TryParse in this particular case.
Using TryParse tells the reader that you are not guaranteed that the input is valid (if you were i'd use parse instead)
And since you are actually trying to parse the input as an int you might as well let the code read Line your intentions
You have two ways to do that
int i;
if (Int32.TryParse(Request.QueryString["Id"], out i))
{
}
or you can do:
try
{
Convert.ToInt32(Request.QueryString["Id"]);
}
catch (FormatException ex)
{
// The field Id it's not convertible
}
catch (Exception ex)
{
// It could throw also ArgumentException or OverflowException
}
It would seem that this:
http://www.kodefuguru.com/post/2010/06/24/TryParse-vs-Convert.aspx
answers your question
Using TryParse would be the best option. Catching exception from convert method is expensive operation. Of course TryParse would only accepts strings while Convert.ToInt32 will take object and can perform conversions (unboxing, down-casting from long/double) apart from parsing.
To cover the ternary operator aspect of this question:
My advice on the use of ternary operators is not to use them if you aren't already so familiar with the code in question that it reads naturally to you. Concision makes the familiar more familiar and the strange, stranger.
When you've groked the discussion about TryParse here enough that you don't even need to think it through conciously anymore, the conversion from if-else to ?: will not just be trivial, it'll be automatic. Until then you're just going to add to your own confusion.
When I'm unfamiliar with something, I drop down to "baby-speak" code at first, learn the new thing, and then integrate it into my normal more concise style after.
use the TryParse method of the int class.
int temp;
if (int.TryParse(Request.QueryString["Id"], out temp)
{ // logic goes here }
If id does not contain a number TryParse will return false.
UPDATE: Changed to show int.TryParse
Is there a simple attribute or data contract that I can assign to a function parameter that prevents null from being passed in C#/.NET? Ideally this would also check at compile time to make sure the literal null isn't being used anywhere for it and at run-time throw ArgumentNullException.
Currently I write something like ...
if (null == arg)
throw new ArgumentNullException("arg");
... for every argument that I expect to not be null.
On the same note, is there an opposite to Nullable<> whereby the following would fail:
NonNullable<string> s = null; // throw some kind of exception
There's nothing available at compile-time, unfortunately.
I have a bit of a hacky solution which I posted on my blog recently, which uses a new struct and conversions.
In .NET 4.0 with the Code Contracts stuff, life will be a lot nicer. It would still be quite nice to have actual language syntax and support around non-nullability, but the code contracts will help a lot.
I also have an extension method in MiscUtil called ThrowIfNull which makes it a bit simpler.
One final point - any reason for using "if (null == arg)" instead of "if (arg == null)"? I find the latter easier to read, and the problem the former solves in C doesn't apply to C#.
I know I'm incredibly late to this question, but I feel the answer will become relevant as the latest major iteration of C# comes closer to release, then released. In C# 8.0 a major change will occur, C# will assume all types are considered not null.
According to Mads Torgersen:
The problem is that null references are so useful. In C#, they are the
default value of every reference type. What else would the default
value be? What other value would a variable have, until you can decide
what else to assign to it? What other value could we pave a freshly
allocated array of references over with, until you get around to
filling it in?
Also, sometimes null is a sensible value in and of itself. Sometimes
you want to represent the fact that, say, a field doesn’t have a
value. That it’s ok to pass “nothing” for a parameter. The emphasis is
on sometimes, though. And herein lies another part of the problem:
Languages like C# don’t let you express whether a null right here is a
good idea or not.
So the resolution outlined by Mads, is:
We believe that it is more common to want a reference not to be null. Nullable reference types
would be the rarer kind (though we don’t have good data to tell us by
how much), so they are the ones that should require a new annotation.
The language already has a notion of – and a syntax for – nullable value types. The analogy between the two would make the language
addition conceptually easier, and linguistically simpler.
It seems right that you shouldn’t burden yourself or your consumer with cumbersome null values unless you’ve actively decided that you
want them. Nulls, not the absence of them, should be the thing that
you explicitly have to opt in to.
An example of the desired feature:
public class Person
{
public string Name { get; set; } // Not Null
public string? Address { get; set; } // May be Null
}
The preview is available for Visual Studio 2017, 15.5.4+ preview.
I know this is a VERY old question, but this one was missing here:
If you use ReSharper/Rider you may use the Annotated Framework.
Edit: I just got a random -1 for this answer. That's fine. Just be aware it is still valid, even though it's not the recommended approach for C#8.0+ projects anymore (to understand why, see Greg's answer).
Check out the validators in the enterprise library. You can do something like :
private MyType _someVariable = TenantType.None;
[NotNullValidator(MessageTemplate = "Some Variable can not be empty")]
public MyType SomeVariable {
get {
return _someVariable;
}
set {
_someVariable = value;
}
}
Then in your code when you want to validate it:
Microsoft.Practices.EnterpriseLibrary.Validation.Validator myValidator = ValidationFactory.CreateValidator<MyClass>();
ValidationResults vrInfo = InternalValidator.Validate(myObject);
not the prettiest but:
public static bool ContainsNullParameters(object[] methodParams)
{
return (from o in methodParams where o == null).Count() > 0;
}
you could get more creative in the ContainsNullParameters method too:
public static bool ContainsNullParameters(Dictionary<string, object> methodParams, out ArgumentNullException containsNullParameters)
{
var nullParams = from o in methodParams
where o.Value == null
select o;
bool paramsNull = nullParams.Count() > 0;
if (paramsNull)
{
StringBuilder sb = new StringBuilder();
foreach (var param in nullParams)
sb.Append(param.Key + " is null. ");
containsNullParameters = new ArgumentNullException(sb.ToString());
}
else
containsNullParameters = null;
return paramsNull;
}
of course you could use an interceptor or reflection but these are easy to follow/use with little overhead
Ok this reply is a bit late, but here is how I am solving it:
public static string Default(this string x)
{
return x ?? "";
}
Use this exension method then you can treat null and empty string as the same thing.
E.g.
if (model.Day.Default() == "")
{
//.. Do something to handle no Day ..
}
Not ideal I know as you have to remember to call default everywhere but it is one solution.