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.
Related
Is there a function in c# that can help to check if the statement is going to return error.
I am aware about try{} catch{} but we can't use it in condition checking. For example:
var opertionResult = SomeRestFunction.Trigger();
string ServerResponse = if(operationResult != null)
{
if(operationResult.Response != null)
{
operationResult.Response.ResponseText;
}
Else
{
"Null";
}
}
Else
{ "Null"; }
In the example above, I need to perform multiple checks to validate the operationResult object properties at multiple levels due to nested objects in it, to determine the final value I want to read and consume as server response value.
If we have some thing like IsError() function in Excel, we can simply try to read the final object property i.e. operationResult.Response.ResponseText; inside of that function and if any of the parent object is null and it has to throw an error it will return false and we can return the value from the else block as shown in the hypothetical example below:
var opertionResult = SomeRestFunction.Trigger();
string ServerResponse = IsError(operationResult.Response.ResponseText)? "Null": operationResult.Response.ResponseText;
So, do we have something like this in C#? Hope this makes sense?
If you're using c# 6 or newer version then you can use null-conditional & null-coalescing-operator operator like below.
Here you need to place ? to check if object is null or not. If object is null then it will not perform any further check and return null. And null-coalescing-operator (??) will be used to check if value is null then it will return value provided afer ??.
string ServerResponse = SomeRestFunction.Trigger()?.Response?.ResponseText ?? "Null";
I'm trying to assign a value to a string variable when making a change to a datagridview field. Unfortunately if it's blank, it crashes with a NullReferenceException even if I try to check if it's null. I also don't know of a more efficient way to write this.
string change = "";
if (dgGroups[cid, rid].Value.ToString() != null) //gets null reference exception if row/column is blank.
{
change = dgGroups[cid, rid].Value.ToString();
}
Your check should be like this. You are trying to call null.ToString() which is not valid and it will throw NullReferenceException .
string change = "";
if (dgGroups[cid, rid].Value != null)
{
change = dgGroups[cid, rid].Value.ToString();
}
If you are using C# 6.0 you can write
string change = dgGroups[cid, rid].Value?.ToString();//this will return null if Value is null
You can use the ?? operator:
change = (dgGroups[cid, rid].Value ?? defaultValue).ToString();
I have this below script in my Class.
aggrgt.Add(new PlainBrgDataSummaryChartAggrgt
{
label = m.label,
goal = m.goal,
groupCode = m.groupCode,
groupValue1 = m.groupValue1,
graphSwitch = m.graphSwitch,
orderByAsc = m.orderByAsc,
metricID = m.metricID,
scoreWk1 = metricscoreWk1.metricScore1,
});
The condition I want is when metricscoreWk1 is null, scoreWk1 = metricscoreWk1.metricScore1 is eliminated.
This may help you:
scoreWk1 = metricscoreWk1.metricScore1 ==null ? 0 : metricscoreWk1.metricScore1
That is, if the value of metricscoreWk1.metricScore1 is null 0(or else any default value) will be assigned else the original value will be assigned to scoreWk1
You can't put "" for Double, the closest analogue, INHO, is Double.NaN (Not A Number):
// Let's have Double.NaN for unknown/undefined etc. value
scoreWk1 = metricscoreWk1.metricScore1 ?? Double.NaN;
You could either:
Create the PlainBrgDataSummaryChartAggrgt object without setting the scoreWk1 field. If metricscoreWk1 is not null, you then set the field and you then add the object to the list.
If you have a setter for metricScore1, you could add a check wherein you ensure that metricscoreWk1 is not null. If it is, the value is not updated.
The second option would allow you to keep your current initialization structure, but the first is more explicit. Should you opt for the second approach, I'd recommend you document it.
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;
}
}
I'm using C# to write a simple program to read Active Directory and display the value held in a AD field on a Windows form program.
If a property doesn't exist then the program crashes, below is my code, how can I catch this and move on to the next field without doing a try/catch for each and every attribute?
DirectoryEntry usr = new DirectoryEntry("LDAP://" + domain, username, password);
DirectorySearcher searcher = new DirectorySearcher(usr);
searcher.Filter = "(sAMAccountName=" + GlobalClass.strUserName + ")";
searcher.CacheResults = false;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("givenName");
searcher.PropertiesToLoad.Add("telephoneNumber");
//program crashes here if telephoneNumber attribute doesn't exist.
textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value.ToString();
Just checking usr.Properties["telephoneNumber"] will not work. You must check the actual value. The reason the error is occuring is because you're calling ToString() on Value which is null.
user.Properties will always return a PropertyValueCollection, regardless of the property name entered into the collections indexer.
I.e.
var pony = usr.Properties["OMG_PONIES"]; // Will return a PropertyValueCollection
var value = pony.Value; // Will return null and not error
You need to check the value itself, the best way through the null coalescing operator:
textBoxFirstName.Text = (usr.Properties["telephoneNumber"].Value
?? "Not found").ToString();
Store the contents of usr.Properties["telephoneNumber"]; in a variable and check for null:
PropertyValueCollection tel = usr.Properties["telephoneNumber"];
textBoxFirstName.Text = (tel != null && tel.Value != null)
? tel.Value.ToString()
: "";
Use the null-coalescing operator (??) operator.
textBoxFirstName.Text = (usr.Properties["telephoneNumber"].Value
?? String.Empty).ToString();
This way the value is replaced with an empty string if null. You could also just return null instead of String.Empty, the reason your code is crashing is because you're trying to call ToString() on a null value.
Something like this should work. If telephoneNumber is not null, it will convert the value to a string, otherwise it will use an empty string.
textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value != null
? usr.Properties["telephoneNumber"].Value.ToString()
: "";
A couple of things will help this be more graceful:
Test usr.Properties["telephoneNumber"] for null before calling child properties like Value. I haven't worked with AD myself, but most string-keyed indexers are designed to gracefully handle non-existent keys. the CLR, on the other hand, will happily throw a NullReferenceException any time you try to reference a member of anything that evaluates to null.
On the off chance that AD DOES blow up on a nonexistent column, enclose the assignment in a Try-Catch block that will show an error on the screen and gracefully continue processing (or not).
Use this code
SearchResult.Properties.Contains("property")
To check if the object actually has the prop loaded from the search result
if (usr.Properties["telephoneNumber"] != null)
textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value.ToString();