hierarchical-data with possible null object [duplicate] - c#

This question already has answers here:
How to check for null in nested references
(6 answers)
Closed 7 years ago.
I have a big hierarchical object and I want one propertie from this structure. The problem is, every level of that object could be null. (It's data from a structured XML)
I want something like this:
_data = record.RltdPties.DbtrAcct.Id.Item
if one of this sub object is null, the data should be also null. Is there a better way the validate my object instead of this:
if(record!=null && record.RltdPties != null && record.RltdPties.DbtrAcct != null && record.RltdPties.DbtrAcct.Id != null)
{
_data = record.RltdPties.DbtrAcct.Id.Item
}
I could make a try{} catch{} block, but that's not a good solution.

with c# 5.0
_data = record?.RltdPties?.DbtrAcct?.Id?.Item

I think a try-catch-block would be the absolute right solution here, because you have to check the whole tree down and it does not look like there are any possible branches in the path of objects. It may not be C#-like but sometimes EAFP (easier to ask forgivenes than permission) keeps it simple enough.
try
{
_data = record.RltdPties.DbtrAcct.Id.Item
}
catch NullReferenceException
{
// do whatever then to do
}

If you can use C# 6.0, you could use the null conditional operator. http://www.codeproject.com/Articles/850832/What-s-new-in-Csharp-Null-conditional-operators
In your case it would be _data = record?.RltdPties?.DbtrAcct?.Id?.Item

Related

c# , how to not repeat a long chain of method calls to check whether an object is null or not before accessing it?

for example,
if(method1().method2().method3().method4().method5().object != null)
{
var value = method1().method2().method3().method4().method5().object;
}
I have came across and written many such scenarios in c#, (ex:- while working with selenium frameworks) where a specific object can only be access through a long chain of method callings, and having to check for null before accessing objects value to not get exceptions. Feels like above code is bit too redundant. What coding pattern is/are used to make above code better? How to not write method calling chain 2 times ?
Even before C# 7, you could just use a local variable:
var something = method1().method2().method3().method4().method5().object;
if (something != null)
{
// Use something
}
In C# 7+ you can also use a pattern:
if (method1().method2().method3().method4().method5().object is object value)
{
// Use value
}
Note that you can't use var for this; the var pattern matches against a null, whereas you want to only match if it's non-null. Just use the appropriate type. (We can't tell what it is from the question...)
You can use the null conditional operator with a local variable. That would save the 2nd call and also checking the null at each method return. You can read about null conditional operator at here.
var result = method1()?.method2()?.method3()?.method4()?.method5()?.object;
if(result != null)
{
var value = result ;
}

How to avoid Tostring exception if string is null? [duplicate]

This question already has answers here:
How to do ToString for a possibly null object?
(12 answers)
Closed 4 years ago.
I want to convert the data row value to sring as follows.
userGuid = dr["user_guid"].ToString();
It may contains Guid or null(Not string empty). If it contains null i got the exception.
How can i overcome this..
I guess you are reading from data reader.
You will have to check if the value is null or DBNull and then you can call to string method.
string user_guid = dr["user_guid"] != DBNull.Value && dr["user_guid"] != null ? dr["user_guid"].ToString() : null ;
Hope this helps.
if (dr[user_guid"] != null) {
//whatever you want to do
} else {
//handle the null value in some way
}
Alternatively,
dr["user_guid"]?.ToString();
The ? is what's called a "null-safe navigator".
This might be useful, one of many ways
userGuid = dr["user_guid"]?.ToString()?? "Default Value";
Please do replace "Default Value" with whatever you feel is appropriate according to your application logic.
Maybe this:
userGuid = dr["user_guid"].ToString() ?? throw new Exception();

C# nullable check optimization [duplicate]

This question already has answers here:
Deep null checking, is there a better way?
(16 answers)
Closed 5 years ago.
Can anyone tell me how do I optimize below code.
if (report != null &&
report.Breakdown != null &&
report.Breakdown.ContainsKey(reportName.ToString()) &&
report.Breakdown[reportName.ToString()].Result != null
)
As others have mentioned, you can use the ?. operator to combine some of your null checks. However, if you're after optimizing for performance, you should avoid the double dictionary lookup (ContainsKey and index access), going for a TryGetValue instead:
MyType match = null; // adjust type
if (report?.Breakdown?.TryGetValue(reportName.ToString(), out match) == true &&
match?.Result != null)
{
// ...
}
Ayman's answer is probably the best you can do for C# 6, for before that what you have there is pretty much the best you can do if all those objects are nullable.
The only way to optimize this further is to be checking if those objects are null before even calling the code, or better yet proofing your platform so this particular function shouldn't even be called in the first place if the values are null.
If you are just getting the value from from the dictionary however you can also simplify with the null coalescing operater '??'
Example:
MyDictionary['Key'] ?? "Default Value";
Thus if the Value at that entry is null you'll get the default instead.
So if this is just a fetch I'd just go
var foo =
report != null &&
report.Breakdown != null &&
report.Breakdown.ContainsKey(reportName.ToString()) ?
report.Breakdown[reportName.ToString()].Result ?? "Default" :
"Default";
But if you are actually doing things in the loop, then yeah you're pretty much at the best you can get there.
For C# 6 and newer, you can do it this way:
if (report?.Breakdown?.ContainsKey(reportName.ToString()) == true &&
report.Breakdown[reportName.ToString()].Result != null)
You can use null conditional operator but only on C# 6
if ( report?.Breakdown?.ContainsKey(reportName.ToString()) == true &&
report.Breakdown[reportName.ToString()].Result != null )
Can you try below? Also probably better to ship it to a method.
// unless report name is already a string
string reportNameString = reportName.ToString();
if ( report?.Breakdown?.ContainsKey(reportNameString) &&
report.Breakdown[reportNameString].Result != null )
{
// rest of the code
}

Is there a way to return null instead of throwing a NullReferenceException? [duplicate]

This question already has answers here:
C# elegant way to check if a property's property is null
(20 answers)
Closed 7 years ago.
I have the following C# problem.
Consider the function:
private String getStringFromNullabel()
{
var nullable = getClass(); // returns some object that could be null
if( nullable != null)
{
return nullable.Text;
}
return null;
}
This works but it is verbose and I would rather write something like:
private String getStringFromNullabel()
{
return NotThrowWrapper(getClass()).Text;
}
This will throw if getClass() returns null.
So I am looking for some syntax that is short enough that this stays a one-liner but rather returns null instead of throwing an exception.
Is there such a thing in C#?
Pre C#6
private String GetStringFromNullabel()
{
var nullable = getClass(); // returns some object that could be null
return nullable != null ? nullable .Text : null;
}
Post C# 6
private String GetStringFromNullabel()
{
return getClass()?.Text;
}
Note that you should follow the .NET naming conventions

how to pass a property by reference in C# [duplicate]

This question already has answers here:
C# Pass a property by reference
(8 answers)
Closed 8 years ago.
I have a process that I want to apply to multiple value-type properties of an arbitrary object, such that each property is modified in some way by the process. A method that applies the process to any given property passed to it would seem to be the way to go, but because the property is a value type it doesn't get changed unless I pass it by reference, but of course the C# compiler prevents properties being passed by reference.
How can I achieve the following without the compiler objecting or having to write messy multiple lines that just repeat the same conditional code for each property?
static internal void AssignStringValueOrLeaveIfNull(string newValue, string sampleValue)
{
if (!string.IsNullOrEmpty(newValue))
sampleValue = newValue;
}
...
AssignStringValueOrLeaveIfNull(value1, anObject.SampleText1);
AssignStringValueOrLeaveIfNull(value2, anObject.SampleText2);
AssignStringValueOrLeaveIfNull(value3, anObject.SampleText3);
AssignStringValueOrLeaveIfNull(value4, anObject.SampleText4);
AssignStringValueOrLeaveIfNull(value5, anObject.SampleText5);
...etc, 30 times.
where anObject.SampleTextn are all strings.
I can't be the first person to have wanted to do something similar!
I'm using VS2008 (C#3.5)
TIA
You cannot. That concept does not exist. You would have to assign the value to a temporary local variable, use ref on the variable, and then assign it back to the property:
var tmp = anObject.SampleText1;
AssignStringValueOrLeaveIfNull(value1, ref tmp);
anObject.SampleText1 = tmp;
Or use a return value, which is probably simpler...
anObject.SampleText1 = AssignStringValueOrLeaveIfNull(value1, anObject.SampleText1);
ref works with:
fields
local variables
array elements
parameters
It does not work with properties, since properties are actually method calls, and the result of a method call does not have a sensible location to ref it from. Note: at the IL level, you can have ref return values from methods, which would theoretically allow for something akin to this - but it is not exposed in C# at the moment (if ever), and it would not work with properties as they exist today.
You could write an ugly extension method that takes an expression representative of the property you want to set, and give it a chance to check whether your new values are null or empty (or different from the destination) before assigning the value.
public static void SetPropertyValue<T>(this T target, Expression<Func<T, string>> memberLamda, string value)
{
// Check if "new value" is null or empty and bail if so
if (string.IsNullOrEmpty(value))
return;
var memberSelectorExpression = memberLamda.Body as MemberExpression;
if (memberSelectorExpression != null)
{
var property = memberSelectorExpression.Member as PropertyInfo;
if (property != null)
{
// Get the existing value and compare against the new value
// Only set the property if it's different from the existing value
if ((string)property.GetValue(target, null) != value)
{
property.SetValue(target, value, null);
}
}
}
}
Source
And then you could use it like:
anObject.SetPropertyValue(a => a.SampleText1, value1);
anObject.SetPropertyValue(a => a.SampleText2, value2);
This should allow you to avoid having the object marked as "dirty", but is rather expensive (as Marc mentioned in a comment on his answer).

Categories

Resources