Null Check before Assignment - c#

Is there a way to check for null before the assignment operation without using the if statement?
Is there a way to provide the following functionality in a single line similar to the null coalescing operator(??) or extension method:
if(myVar != null){ obj = myVar;}
I tried to use an extension method but extension methods don't allow the use of the ref or out keywords as the first parameter. I can't seem to find any built in operator that does this.
The point is to avoid the assignment because the obj's propertyset property is set to true no matter what it is being set to null or otherwise.
meaning obj = myVar ?? null; will not work, nor will obj = myVar != null ? myVar : null;
I could possible use a static method but where should the method live? Utility class? A static method in an object extension class?
Are these the only options single line ifs or static methods?
EDIT:
I don't have access to the obj it is one of many third party objects provided to me as is.
EDIT 2:
I have a large amount of code that looks similar to the following:
this.Header.InvoiceHeader.InvoiceTypeCode = row.Field<string>("InvoiceTypeCode");
this.Header.InvoiceHeader.PurchaseOrderDate = row.Field<DateTime?>( "PODate" ) ?? DateTime.Now;
this.Header.InvoiceHeader.PurchaseOrderNumber = row.Field<string>( "PONumber" );
this.Header.InvoiceHeader.SellersCurrency = row.Field<string>( "Currency" ) ?? "USD";
this.Header.InvoiceHeader.BuyersCurrency = row.Field<string>( "Currency" ) ?? "USD";
this.Header.InvoiceHeader.TradingPartnerId = this.EDITradingPartner.TradingPartnerID;
this.Header.InvoiceHeader.CustomerAccountNumber = row.Field<string>("CustomerAccountNumber");
this.Header.InvoiceHeader.CustomerOrderNumber = row.Field<string>("CustomerOrderNumber");
this.Header.InvoiceHeader.PromotionDealNumber = row.Field<string>("PromotionDealNumber");
This is mapping my db to a third party xml object that has too many nodes to write a wrapper for each node. The xml object outputs an empty tag if the value of the property is set to null. in other words if I don't want the tag to exist then don't set it.

If you have a smart setter, that actually knows when it's value changed instead of just checking whether it was called, you could do this:
obj = myVar ?? obj;
If you don't have a smart setter, there is no way around an if. Where you want to place that is completely up to your and your coding preferences.

Since I'm assuming that obj is a variable and not a property, this is the equivalent, but personally I find the if much easier to read:
obj = myVar ?? obj;
Note that if obj is just a variable then there are no side-effects when setting it to itself, however if you try this with a property:
obj.MyProperty = myVar ?? obj.MyProperty;
Then you are invoking a getter and setter if myVar is null; either of which may have side effects that would not occur with the original if statement.

I recommend to use some method. If you will use this logic in different classes util class is what you need, otherwise use private method, or inherit from base class with protected implementation.
private void SetValue(ref object property, object value)
{
if (property != null) {
property = value;
}
}

Related

Assignment of property if not null, possible with null-coalecing?

I'm trying to do smth like
Im trying to assign property on an object if this object is not null.
but standard form of non-null invocation does not work for assignment like this
socket?.Blocking = false
what I'm trying to do is shorten this if possible:
if(socket != null) socket.Blocking = false
This would be a great feature
b?.c = "bob"
Though, it's flawed when it comes to compound assignments. Consider this
a.b?.c = "bob"
What should it do on null?
Personally, I think it should just ignore the parents. But alas, the powers that be have probably made the right decision to disallow this because of inconsistency with the other use cases of null conditional.
Note : you could roll your own an extension method, though it's not very satisfying, and would probably fail my code reviews just on abstractness and readability.
a?b.NullConditional(x => x.c = "bob");
You are left with
if(a?.b != null) a.b.c = "bob"
or in your case
if(socket != null) socket.Blocking = false
or to write a dedicated extension method for this use case.
I think the only way would be to use an extension method, so you could write:
socket?.SetBlocking(false);
You can create the extension method like this:
public static class SocketExtensions
{
public static void SetBlocking(this Socket socket, bool blocking)
{
if (socket != null) socket.Blocking = blocking;
}
}

C# null-conditional shorthand for method arguments

The null-conditional operator is very useful when the method belongs to the object in question, but what if the object in question is an argument? For example, can this be shortened?
var someList = new List<SomeType>();
if (anotherList.Find(somePredicate) != null)
{
someList.Add(anotherList.Find(somePredicate))
}
One solution I thought of was to use an extension method like below:
public static void AddTo<T>(this T item, List<T> list)
{
list.Add(item);
}
With that the first code block can be reduced to:
var someList = new List<SomeType>();
anotherList.Find(somePredicate)?.AddTo(someList);
But this solution is specific to this example (i.e. adding an object to a list if it's not null). Is there a general way to indicate that if a parameter is null, the method should not be run?
Never do this
var someList = new List<SomeType>();
if (anotherList.Find(somePredicate) != null)
{
someList.Add(anotherList.Find(somePredicate))
}
this will search the list twice which is unnecessary. use a temporary variable instead.
var someList = new List<SomeType>();
var find = anotherList.Find(somePredicate);
if (find != null) someList.Add(find);
Is there a general way to indicate that if a parameter is null, the method should not be run?
Currently there is no such feature. how ever there are other alternatives that work better like in other answers provided.
You could also use just:
var someList = new List<SomeType>();
someList.AddRange(anotherList.Where(somePredicate));
In your case you probably need to make sure that your predicate only finds at max one element.
TLDR: Not yet.
The team plans to implement a functionality into the language, that would do this exact thing. It would look something like this:
someList.Add(anotherList.Find(somePredicate) ?? return);
In which the ?? return checks whether the first argument is null, and if it is, than it returns. (Or you could write break if that is what you want)
I am not sure if this is a thing they are working on at the moment, and if it will be included in the next version of C#, but would go a long way if it is going to be.

Proper null check

I am instantiating an Associate object and assigning properties to it from txtboxes inside of my main form. What is the best practice for null checking? Is it to check each and every property with an if statement before I assign it or is there something a bit better? Here is my code:
Associate updateAssociate = new Associate();
updateAssociate.AssocID = txtAssocId.Text;
updateAssociate.FirstName = txtFname.Text;
updateAssociate.LastName = txtLname.Text;
updateAssociate.HireDate = Convert.ToDateTime(txtHireDate.Text);
updateAssociate.ContractEndDate = Convert.ToDateTime(txtContractEnd.Text);
updateAssociate.TerminationDate = Convert.ToDateTime(txtTerminationDate.Text);
updateAssociate.FullPartTimeID = cboFullPart.SelectedText;
updateAssociate.PrimaryRole = cboPRole.SelectedText;
Based on your comment to the question:
If it is a text box then it would be the .Text property I would want to check for null or blank values before I assign them to the object
You can use the null coalescing operator to check for null values when assigning like that:
updateAssociate.AssocID = txtAssocId.Text ?? string.Empty;
or:
updateAssociate.AssocID = txtAssocId.Text ?? someDefaultValue;
That way if txtAssocId.Text is null then you would assign your defined default to the object property instead of null.
Though I'm not entirely sure a TextBox's .Text property would ever be null instead of an empty string. Maybe you want to check for both?:
updateAssociate.AssocID = string.IsNullOrEmpty(txtAssocId.Text) ? someDefaultValue : txtAssocId.Text;
In C# 6 it would be null-conditional operator.
updateAssociate.AssocID = txtAssocId?.Text;
In prior versions of c# you can write a method to eliminate code duplication. Something like this:
public static T CheckNull<T>(Func<T> canBeNull) where T : class
{
try
{
return canBeNull();
}
catch (NullReferenceException)
{
return default(T);
}
}
And use it like this
updateAssociate.AssocID = CheckNull(() => txtAssocId.Text);
Then you can wrap any code that can throw a null reference into lambda, pass it to this method and no longer bother with it.

initializing an object with strings to null

I have an object model somewhat like this:
public class MyObject
{
public string String1 { get; set; }
public string String2 { get; set; }
...
}
When the object initializes, all the string values are set to null.
Later on, I'm writing a method that evaluates the value of these strings to prepare an update in the DB. Something like this:
if (TheObject.String1 != null) { TheObjectInDB.String1 = TheObject.String1; }
if (TheObject.String2 != null) { TheObjectInDB.String2 = TheObject.String1; }
TheObject is an instance of MyObject and TheObjectInDB is an instance of the linq-to-sql map for the table I'm updating.
My question is this: is using the null a safe way to do it or could it cause problems later? Should I create a constructor that initializes these strings to "" and in the update check if the strings are = "" instead of = null?
Thanks for the advice.
There is nothing more, or less safe about null or an empty string. It is entirely your choice. Because both are often used to indicate the abscence of data or information, there is a convenience method string.IsNullOrEmpty that allows you to accept either value.
In your case, I would stick with the easiest option, null.
You could initialize both properties to string.Empty (preferred to "") and then check for string.Empty when setting the properties, however only if you can guarantee that either:-
a) the value being set is never string.Empty
or
b) the value being set is string.Empty but the values are only set once
I'd stick with checking for null to avoid either of the above causing potential issues in the future.
There is no problem here, the code you are using should work without any problems.
I can't even think of 'problems that this can cause 'later''.

Good practices for initialising properties?

I have a class property that is a list of strings, List.
Sometimes this property is null or if it has been set but the list is empty then count is 0.
However elsewhere in my code I need to check whether this property is set, so currently my code check whether it's null and count is 0 which seems messy.
if(objectA.folders is null)
{
if(objectA.folders.count == 0)
{
// do something
}
}
Any recommendation on how this should be handled?
Maybe I should always initialise the property so that it's never null?
When I have List as a property, I usually have something that looks like the following (this is not a thread safe piece of code):
public class SomeObject
{
private List<string> _myList = null;
public List<string> MyList
{
get
{
if(_myList == null)
_myList = new List<string>();
return _myList;
}
}
}
Your code would then never have to check for null because the Property would be initialized if used. You would then only have to check for the Count.
Right now your code will Always throw a Null Pointer exception, you are checking for Null and if it IS null - you're trying to access an object which does not exist.
If for your application the collection being a null reference never has a different meaning than the collection being empty, then yes, I would say you should always initialize it and this way remove the null checks from the remaining code.
This approach only makes sense if the property setter does not allow to change it to a null reference after initialization.
You have three options (and you need to decide based on your project):
Create a method to check for NullOrNoElements. Pro: Allows both null and no entries. Con: You have to call it everywhere you want to use the property.
Preinitialize with a list. Pro: Thread-save and very easy. Con: will use memory even when not used (depending on how many instances you have this may be a problem)
Lazy initialize Pro: Does only use memory when really used. Con: NOT thread save.
private List<string> lp = null;
public List<string> ListProp
{
get
{
if(lp == null)
lp = new List<string>();
return lp;
}
}
You could always initialize the property so it's an empty List. Then you can just check the count property.
List<String> Folder = Enumerable.Empty<String>();
I once wrote an extension method for ICollection objects that checked if they were null or empty
public static Boolean IsNullOrEmpty<T>(this ICollection<T> collection)
{
return collection == null ? true : collection.Count() == 0;
}
public static Boolean IsPopulated<T>(this ICollection<T> collection)
{
return collection != null ? collection.Count() > 0 : false;
}
You could do this in a single IF
if(objectA.folders is null || objectA.folders.count == 0)
Or you could create a boolean property in the class which checks this status for you and returns a result
public bool objectA.FolderIsNullOrEmpty
{
get { return objectA.folders is null || objectA.folders.count == 0;}
}
If it does not make a difference to your application, I would rather recomend initializing the List to start with.
You could handle this by initializing the object in the constructor. This is usually where this type of thing is done. Although I see nothing wrong with your current code. No point in initializing stuff that doesn't exist yet, it just wastes memory.
Its a good question. I would add a method to objectA FoldersNullOrEmpty() that you can use eg
public virtual FoldersNullOrEmpty()
{
return (folders == null || folders.count == 0)
}
I almost always initialize lists and even make sure they can't be set to null if exposed by any setters. This makes using them much easier.

Categories

Resources