Handling null objects in object setters - c#

I am trying to use a nice near object setter, but have null issues.
My code right now:
var Result = new RefundReplyObject
{
AuthorisationNumber = reply.refundResponse.transactionDetails.authorisationNumber,
ChargeValue = reply.refundResponse.transactionDetails.totalAmount.amount,
Message = reply.refundResponse.transactionDetails.message,
ReconciliationReference = reply.refundResponse.transactionDetails.reconciliationReference,
SettlementDate = reply.refundResponse.transactionDetails.settlementDate,
Status = TransactionStatusToLocalModel(reply.refundResponse.transactionDetails.status),
TransactionReference = reply.refundResponse.transactionDetails.transactionReference
};
BUT ... 'totalAmount' might be null. So, I get errors.
Is there a neat way to handle this, so that if 'totalAmount' is null, then set chargevalue to zero?

How about a ternary operator, that checks to see if total amount is null. If it isn't, then use it's amount, otherwise 0.
ChargeValue = (reply.refundResponse.transactionDetails.totalAmount != null) ? reply.refundResponse.transactionDetails.totalAmount.amount : 0,

You could do, for example:
ChargeValue = reply.refundResponse.transactionDetails.totalAmount != null ? reply.refundResponse.transactionDetails.totalAmount.amount : 0

ternary operator to the rescue!
ChargeValue = totalAmount ? totalAmount.amount : 0;

Something like this?
ChargeValue = (null == reply.refundResponse.transactionDetails.totalAmount)
? 0
: reply.refundResponse.transactionDetails.totalAmount.amount

You're not going to be able to do it on the setter side of things since the exception is occuring before you even get there. You can get what you're after (and clean up your code substantially in the process) by doing something like this:
var trans = reply.refundResponse.transactionDetails;
var Result = new RefundReplyObject
{
AuthorisationNumber = trans.authorisationNumber,
ChargeValue = trans.totalAmount == null ? 0 : trans.totalAmount.amount,
Message = trans.message,
ReconciliationReference = trans.reconciliationReference,
SettlementDate = trans.settlementDate,
Status = TransactionStatusToLocalModeltrans.status),
TransactionReference = trans.transactionReference
};

Related

C#: What is this statement doing? dynObj.#switch == 1 ? true : false

I recently took over some code and came a across a statement that I wasn't sure what it was doing so I decided to post it.
currCarbon.CleanGeneration = (dynObj.#switch == 1 ? true : false);
Since 'dynObj' is a dynamic object holding a json value, is it checking if 'dynObj' contains a 'Switch' key / value?
Thanks for you help!
dynamic dynObj = GetValues();
if (dynObj != null) //json string from API
{
// Read the first record's carbon index
var prevCarbon = _dbContext.WatttimeApilog.OrderByDescending(c => c.CreatedDate).FirstOrDefault();
if (prevCarbon == null) //NO previous carbon value from database
{
//Plug in default values
currCarbon.Percentage = defaultPercent;
currCarbon.CleanGeneration = false;
currCarbon.Rating = defaultRating;
currCarbon.ValidUntil = DateTime.UtcNow;
insertFlag = true;
}
else
{
currCarbon.Percentage = dynObj.percent;
currCarbon.CleanGeneration = (dynObj.#switch == 1 ? true : false);
currCarbon.Rating = Convert.ToByte(dynObj.rating);
currCarbon.ValidUntil = dynObj.validUntil;
}
It's setting CleanGeneration to true or false based on whether or not #switch is equal to one via a ternary operator.
EDIT: The code isn't the most clean and can be shortened to just currCarbon.CleanGeneration = dynObj.#switch == 1;
Linked is docs on the ternary operator:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator

Checking if value is null before assigning

so I am creating a new object and setting its properties from other functions. I need to check if those are null before applying the values. How would I approach this?
Customer = new Customer (
name = requestCall.Name,
age = requestCall.Age.ofType<DateTime>().DOB
)
how would I check if requestCall.Age or requestCall.Name is not null before applying?
Depending on your scenario you can use ternary operator
name = requestCall.Name == null ? something : something_else
or null coalesce operator
name = requestCall.Name ?? something
Variant 1:
Customer = new Customer(
name = requestCall.Name ?? "default name",
age = requestCall.Age == null ? (some default date) : requestCall.Age.ofType<DateTime>().DOB
);
Variant 2:
Customer = requestCall == null ? null : new Customer(
name = requestCall.Name,
age = requestCall.Age.ofType<DateTime>().DOB
);
Of course, you can use if and to my mind, it is better:
Customer customer;
if (requestCall != null)
{
customer = new Customer();
if (requestCall.Name != null)
{
customer.Name = requestCall.Name;
}
// etc.
}
else
{
customer = null;
}
Just make a requestCall.IsValid() method (aptly named something that fits in with your usage) and use this to verify whether or not you are able to make a new customer.
I'd imagine the logic will grow as you determine other things that need to be added and this will reduce the amount of updating you'll have to do.
As a side note to this: You may wish to make a constructor that takes in a requestCall as a parameter.
Do it as
requestCall.Name ?? "soome text",
or !string.IsNullOrEmpty(requestCall.Name) ? requestCall.Name : "soome text" ,
and check null for integer as
`age = requestCall.Age == null ? (default) : requestCall.Age.ofType<DateTime>().DOB`
try this
Customer = new Customer (
name = requestCall.Name ?? string.Empty,
age = requestCall.Age.ofType<DateTime>().DOB ?? DateTime.Now
)

How to handle null values from SQLite DB with C#?

EDIT:
Thanks to everyone who replied! I appreciate all of your answers :)
So I have a class with the following constructor:
public Transaction(DataRow row)
{
LastName = row.Field<string>("LastName");
FirstName = row.Field<string>("FirstName");
MI = row.ItemArray[3].ToString()[0];
ContactNumber = row.ItemArray[4].ToString();
Hours = int.Parse(row.ItemArray[5].ToString());
CheckIn = (DateTime)row.ItemArray[6];
roomNumber = int.Parse(row.ItemArray[9].ToString());
//Paid = row.Field<int>("Paid");
//TotalBill = row.Field<int>("TotalBill");
}
Notice I have 2 of them commented out with /'s That's because if I don't they return null values even if I try ''row.Field([Whatever]).GetValueOrDefault()'', it still comes out null and my constructor returns null. I also have my DB set with default values so IDK what's wrong.
Anyone got a work around? :)
The DataRow class has a method that is called IsNull and that could receive the column name.
Just combine it with the conditional operator
Paid = row.IsNull("Paid") ? 0 : row.Field<int>("Paid");
the same is true for all other fields that could contain a null value.
Just check for null first and supply a default value:
public Transaction(DataRow row)
{
LastName = row.Field<string>("LastName");
FirstName = row.Field<string>("FirstName");
MI = row.ItemArray[3].ToString()[0];
ContactNumber = row.ItemArray[4].ToString();
Hours = int.Parse(row.ItemArray[5].ToString());
CheckIn = (DateTime)row.ItemArray[6];
roomNumber = int.Parse(row.ItemArray[9].ToString());
Paid = row.Field<int?>("Paid") ?? 0;
TotalBill = row.Field<int?>("TotalBill") ?? 0;
}
See the ?? Operator (C# Reference) page on MSDN for further information on the ?? operator.
You can simply use the Nullable type and GetValueOrDefault method or use null coalescing operator.
Paid = row.Field<int?>("Paid").GetValueOrDefault()
or
Paid = row.Field<int?>("Paid") ?? 0
In both cases Paid will have a value of 0, you can change if you want.
Create your own little function that does a simple check.
Along the lines of:
public integer GetNumber (object val)
{
if (IsNumeric (val))
{
return val;
} else
{
return 0;
}
}
I'm not fantastic with C#, but that should give you an idea. Sorry about formatting, I'm on a phone which doesn't help at all.

Logic to check for Null Value in Multiple Textboxes

Hi guys, probably a simple one.
Using C# .Net 4.0 and Visual Studio 2012 Ultimate.
Got the following code:
string part = "";
part = txtIOpart.Text;
txtBatchCV.Text = txtBatchIO.Text;
txtPartCV.Text = part;
txtExternalCV.Text = Sqlrunclass.SplitSpec_External(part, pg);
txtInternalCV.Text = Sqlrunclass.SplitSpec_Internal();
txtABSCV.Text = Sqlrunclass.SplitSpec_cvABS();
txtOilCV.Text = Sqlrunclass.SplitSpec_OilSeal();
txtBarCV.Text = "*" + Sqlrunclass.SplitInfo_ASno(part, pg) + "*";
txtBarNumCV.Text = txtBarCV.Text;
txtLocnCV.Text = Sqlrunclass.SplitInfo_Location();
txtFitsCV.Text = Sqlrunclass.SplitInfo_Desc();
txtHeightCV.Text = Sqlrunclass.SplitSpec_Height();
txtDiameterCV.Text = Sqlrunclass.SplitSpec_Diameter();
txtCirclitCV.Text = Sqlrunclass.SplitSpec_Circlit();
picTypeCV.Image = ftpclass.Download("CVspecType" + Sqlrunclass.SplitSpec_TypeCV() + ".jpg", "ftp.shaftec.com/Images/TypeJpg", "0095845|shafteccom0", "4ccc7365d4");
if (txtBatchCV.Text == null || txtBatchCV.Text == "")
{
txtBatchCV.Text = "ALL";
}
As you can see at the bottom I'm checking the batch, but I need to check all of the data thats being set by a bunch of methods. Each one will have a different txt output if it sees a null or blank txt. Is there anyway to shorten this code?
Try, txtBatchCV.Text For example
//Just for null
txtBatchCV.Text = (txtBatchCV.Text ?? "ALL").ToString();
//for both null and empty string
txtBatchCV.Text = string.IsNullOrEmpty(txtBatchCV.Text) ? "ALL": txtBatchCV.Text;
You could iterate through all the textboxes
foreach (var txt in form.Controls.OfType<TextBox>())
{
switch(txt.Id){
case "txtBatchCV":
// Do whatever you want for txtBatchCV e.g. check string.IsNullOrEmpy(txt.Text)
break;
}
}
I borrowed the above from here:
How do I loop through all textboxes and make them run corresponding actions from action dictionary?
In response to the comment I got from Tim, I've added a bit more code to explain what you could do. My code example was never meant to be a full solution.
TextBox.Text is never null, it will return "" then. If your methods return null you could use the null-coalescing operator:
string nullRepl = "ALL";
txtExternalCV.Text = Sqlrunclass.SplitSpec_External(part, pg) ?? nullRepl;
txtInternalCV.Text = Sqlrunclass.SplitSpec_Internal() ?? nullRepl;
txtABSCV.Text = Sqlrunclass.SplitSpec_cvABS() ?? nullRepl;
txtOilCV.Text = Sqlrunclass.SplitSpec_OilSeal() ?? nullRepl;
txtLocnCV.Text = Sqlrunclass.SplitInfo_Location() ?? nullRepl;
txtFitsCV.Text = Sqlrunclass.SplitInfo_Desc() ?? nullRepl;
txtHeightCV.Text = Sqlrunclass.SplitSpec_Height() ?? nullRepl;
txtDiameterCV.Text = Sqlrunclass.SplitSpec_Diameter() ?? nullRepl;
txtCirclitCV.Text = Sqlrunclass.SplitSpec_Circlit() ?? nullRepl;
For starters you could use string.IsNullOrEmpty(txtBatchCV.Text), it's a convevience method that basically does what you do in the if check.
You can atleast use one of these methods:
string.IsNullOrEmpty(txtBatchCV.Text)
or
string.IsNullOrWhitespace(txtBatchCV.Text)
I would try something like this:
void SetDefaultIfNull(TextBox txt, string defaultVal)
{
if (string.IsNullOrWhitespace(txt.Text))
txt.Text = defaultVal;
}
Then pass each textbox and the default to the method.

Linq and DBNull - Getting error

I'm getting an error when selecting from a rows.AsEnumerable(). I am using the following code...
var rows = ds.Tables[0].AsEnumerable();
trafficData = rows.Select(row => new tdDataDC
{
CalculationCount = row.Field<Int64>("biCalculationCountSeqID")
, Zone = row.Field<Int16>("siFkZoneId")
, Miles = row.Field<decimal>("dcMiles")
, Plaza = row.Field<Int16>("siFkPlazaId")
, VehicleCount = row.Field<int>("iVehicleCount")
});
Most of the time it works well, but when there are NULLS in the database I'm getting this error "Cannot cast DBNull.Value to type 'System.Int16'. Please use a nullable type.."
How can I correct this? I don't want my datacontracts to have Nullable types, I'd like to use a ternary or something, and if a value is NULL, just use 0. Is this possible?
Thanks for any help,
~ck
You could always add another extension method (untested):
public static T FieldOrDefault<T>(this DataRow row, string columnName)
{
return row.IsNull(columnName) ? default(T) : row.Field<T>(columnName);
}
Then your callsite looks like:
var rows = ds.Tables[0].AsEnumerable();
trafficData = rows.Select(row => new tdDataDC
{
CalculationCount = row.FieldOrDefault<Int64>("biCalculationCountSeqID")
, Zone = row.FieldOrDefault<Int16>("siFkZoneId")
, Miles = row.FieldOrDefault<decimal>("dcMiles")
, Plaza = row.FieldOrDefault<Int16>("siFkPlazaId")
, VehicleCount = row.FieldOrDefault<int>("iVehicleCount")
});
Here is how you test for nulls...
Plaza = row.IsNull("siFkPlazaId") ? 0 : row.Field<int>("siFkPlazaId")
If your property is nullable you can do this as well;
Plaza = row.Field<int16?>("siFkPlazaId")
I'm pretty fond of the ?? operator:
CalculationCount = row.Field<Int64?>("biCalculationCountSeqID") ?? 0
, Zone = row.Field<Int16?>("siFkZoneId") ?? 0
, Miles = row.Field<decimal?>("dcMiles") ?? 0.0m
, Plaza = row.Field<Int16?>("siFkPlazaId") ?? 0
, VehicleCount = row.Field<int>("iVehicleCount") 0;

Categories

Resources