I want to combine two IList's into one, either of which, or both, could be null. If both are null I want the result to be null.
I have this but I want something more elegant but still easy to read.
private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second)
{
IList<Filter> result = null;
if(first != null)
if (second != null)
result = first.Concat(second) as IList<Filter>;
else
result = first;
else if (second != null)
result = second;
return result;
}
I would think it’s a bit of a weird behavior if I call your CombineFilters with two lists (one possibly null) and get back a list which is not a copy. That would result in the following behavior:
List<Filter> filters1 = new List<Filter>() { new Filter() };
List<Filter> filters2 = null;
Console.WriteLine(filters1.Count); // 1
var filters = CombineFilters(filters1, filters2);
filters.Add(new Filter());
Console.WriteLine(filters.Count); // 2
Console.WriteLine(filters1.Count); // also 2
I’m not sure if I would really expect this behavior.
So I would suggest you to always ensure that there will be a new list in the end. This allows you to make this really short:
private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second)
{
return (first ?? Array.Empty<Filter>()).Concat(second ?? Array.Empty<Filter>()).ToList();
}
Use Enumerable.Concate together with the ?? operator:
if(first == null && second == null)
return null;
return Enumerable.Concat(first ?? Enumerable.Empty<IFilter>(),
second ?? Enumerable.Empty<IFilter>()).ToList();
If either first or second are null a new list will be used instead for the concat.
I think that in case both lists are null then still an initialize collection should be returned. In that case just remove the if statement. Also maybe return an IEnumerable instead of IList:
private IEnumerable<Filter> CombineFilters(IEnumerable<Filter> first, IEnumerable<Filter> second)
{
return Enumerable.Concat(first ?? Enumerable.Empty<IFilter>(),
second ?? Enumerable.Empty<IFilter>());
}
Returning the IEnumerable instead of the IList depends on your scenario. Read more here:
Should I always return IEnumerable<T> instead of IList<T>?
Should I return an IEnumerable or IList?
private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second)
{
if (first == null && second == null) return null;
first = first ?? new List<Filter>();
second = second ?? new List<Filter>();
return first.Concat(second).ToList();
}
You could do something like this:
private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second)
{
if (first == null && second == null)
{
return null;
}
return (first ?? Enumerable.Empty<Filter>())
.Concat(second ?? Enumerable.Empty<Filter>())
.ToList();
}
That said, it's a good practice to avoid null collections entirely; if there are no elements, you just return an empty collection. This way, you don't need to check for null all the time. This may not be possible to do in your case, but if it is, it will make your code quite a bit cleaner.
Also, consider using IEnumerable<T> rather then IList<T> as it is a more general abstraction (and also because IList<T> is a broken, leaky abstraction - implementations throw exceptions (!) for methods they don't support). On the other hand, I can see that this is a private method, and if you are actually always passing List<Filter>, it's probably better to declare the parameters as List<Filter>.
EDIT:
Just noticed my answer is very similar to the one posted by Gilad Green, which I didn't see before.
Related
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;
}
}
I cam across this line while going through some not that old code and don't understand why anyone would ever do it:
return dbStudents.MethodToReturnAllStudents()?.Select(x => new dtoStudent(x));
MethodToReturnAllStudents returns an IEnumerable<SQLDomain.Student> (dtoStudent) is in a different namespace -- all the SQLDomain.Student has been mapped from an IDataRecord.
Why would there be a ? in the middle of this statement. Will the LINQ Select try to do anything if MethodToReturnAllStudents returns null?
Is this just terrible code all around?
Side note: Either way, I am refactoring it to follow some alternative standards and to be much more readable.
This is not "old code", since this is a C#6 feature, the Null Conditional Operator. When used, it checks if the immediately preceding value is null before allowing property/method usage on that instance. If it is null, it returns null.
In this scenario, you can translate this code to:
var students = dbStudents.MethodToReturnAllStudents();
if (students == null) return null;
return students.Select(x => new dtoStudent(x));
However, there is actually a larger potential issue with this code than the unfamiliar operator.
The general consensus is that IEnumerable<T> should never return null and, as such, should never need to be null checked. It should always return a sequence that is either hydrated or empty.
That said, if this were in fact List<T> (or a null IEnumerable, although less common), this could be a real scenario (although I would still advocate for never returning null but rather an empty list).
You will have to decide as a development team if the Null Conditional Operator is more succinct and readable. Personally, I'm a fan of it, just not in this context since it is indicative of a larger design smell.
It's not "terrible" code, but it's non-intuitive if you're not familiar with the syntax. I personally enjoy the less-verbose options. LINQ will stop if MethodToReturnAllStudents() returns null and just return that null. It's basically saying
var retVal = dbstudents.MethodToReturnAllStudents();
if(retVal == null) {
return retVal;
} else {
return retVal.Select(x => new dtoStudent(x));
}
Now as users have pointed out, it shouldn't return null as the caller is expecting an IEnumerable.
var retVal = dbstudents.MethodToReturnAllStudents();
if(retVal == null) {
return new List<student>();
} else {
return retVal.Select(x => new dtoStudent(x));
}
Using a null coalescing operator makes the code even more concise and still properly handles return types so it doesn't return null:
return dbStudents.MethodToReturnAllStudents()?.Select(x => new dtoStudent(x)) ?? new List<student>();
It is the Null Conditional Operator
MSDN Documentation
If dbStudents.MethodToReturnAllStudents() is null, it will return null instead of executing .Select(x => new dtoStudent(x)) which would result in a NullReferenceException.
I am having this Linq To SQL query which is taking Customer Category from database.The CustCategory will be defined already.Here is the query.
public IList<string> GetAccountType()
{
using (var db = new DataClasses1DataContext())
{
var acctype = db.mem_types.Select(account=>account.CustCategory).Distinct().ToList();
if (acctype != null)
{
return acctype;
}
}
}
Currently I am getting an error that Not all code paths return a value.If I am always certain that the value is there in the database then do I need to check for null,If I need to check for null then how do I handle this.
Can anyone help me with this.
Any suggestions are welcome.
Since Enumerable.ToList never returns null (see the Return Value section of the documentation), you can safely remove the if.
EDIT: Note that, no matter what your database contains, acctype will never be null:
If no value is found in the database, the return value will be an empty list (which is different than null).
If one record is found and its value is null, the return value will be a valid list with one entry, whose value is null. Still, the list itself is not null.
What happens if:
if (acctype != null)
Is null? What is your method supposed to return?
You need to return something
This is not about LINQ to SQL, the method GetAccountType() must return IList<string>. You should return return acctype; and then check this returned list later using Any(), something like:
if(GetAccountType.Any()){
//not empty
}
How about something like this for a fairly clean and readable solution?:
(Note, updated: removed the check for null, since it would clearly not have any effect).
public IList<string> GetAccountType()
{
var acctype = new List<string>();
using (var db = new DataClasses1DataContext())
{
acctype = db.mem_types.Select(
account=>account.CustCategory).Distinct().ToList();
}
return acctype;
}
You need to return a value from your function:
public IList<string> GetAccountType()
{
using (var db = new DataClasses1DataContext())
{
var acctype = db.mem_types.Select(account=>account.CustCategory).Distinct().ToList();
if (acctype != null)
{
return acctype;
}
}
return acctype;
}
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.
I have a large C# (3.0) object structure originating from a deserialized XML document. I need to know whether a variable deep in the hierarchy is null. The way I do this now is to check every parent object on the way down for null, but this leads to a long repetition of if statements.
I am trying to avoid expensive try-catch blocks.
Is there a smarter way to do this?
edit:
For example after a deserialization of an XML application form into an object hierarchy structure there could potentially be a salary value under
applicationForm.employeeInfo.workingConditions.salary
but to find out safely I have to write something like
if (applicationForm.employeeInfo != null)
if (applicationForm.employeeInfo.workingConditions != null)
if (applicationForm.employeeInfo.workingConditions.salary != null)
because simply using the latter if-statement will of course fail if one of the parent objects is null.
So I am looking for any smarter way to handle this situation.
You've run into the classic situation where each step in A.B.C.D may yield null. Though this is a common scenario, surprisingly there's no common pattern for solving it, other then using a large if-statement with lots of or's (||).
If each step can return a different class, then there's a rarely used pattern that you can apply: Use a generalized generic extension method with method chaining.
A generalized extension method is not a fixed term but I use it here for emphasizing that the ext. method is applicable to almost all types of objects, hence generalized. According to Bill Wagner in Effective C#, this is bad design. But in some remote cases, like yours, you can use it as long as you know what you're doing and why.
The trick is simple: define a generic extension method and generalize it for all classes that have a default constructor. If the test fails (object is null), the method returns a new object of the same type. Otherwise, it will return the unchanged object itself.
Why is this a good approach for your scenario? Because you don't need to change any existing classes, because it's understandable and promotes readable code, because it keeps type safety (compile time errors instead of runtime errors) and it's simply more concise compared to other approaches.
// extension method:
public static class SomeExtentionMethods
{
public static T SelfOrDefault<T>(this T elem)
where T : class, new() /* must be class, must have ctor */
{
return elem ?? new T(); /* return self or new instance of T if null */
}
}
// your code now becomes very easily readable:
Obj someObj = getYourObjectFromDeserializing();
// this is it applied to your code:
var mySalary = applicationForm.SelfOrDefault().
employeeInfo.SelfOrDefault().
workingConditions.SelfOrDefault().
salary;
// now test with one if-statement:
if(mySalary.IsEmpty())
// something in the chain was empty
else
// all's well that ends well :)
The beauty of this approach is that it works with all types of classes (provided they have a ctor), including collections and arrays. If any step is an index step, it will still work (depending on the collection, an invalid index can return null, default or raise an exception):
var x =
someObj.SelfOrDefault()
.Collection.SelfOrDefault()
.Items[1].SelfOrDefault()
.Mother.SelfOrDefault()
.Father.SelfOrDefault();
Update: expanded a bit and added a more elaborate example
Update: renamed NotNull, which implies boolean, to SelfOrDefault, which follows LINQ's naming convention (FirstOrDefault etc) and implies what it does.
Update: rewritten and reorganized, made code more applicable, hoping to make it more understandable overall :)
Firstly, if you're repeating the logic in more than one place, encapsulate it in a method.
Secondly, you don't need lots of if statements, you just need one with a lot of OR conditions:
if(parent==null ||
parent.Child == null ||
parent.Child.GrandChild == null ...
Thirdly, "avoiding expensive try/catch blocks" may be a premature optimization, depending on your scenario. Have you actually tried this and profiled it, and is it really causing a large overhead?
You can nest ternary operators. Still a pain, but not as bad as nested ifs.
string salary = (applicationForm.employeeInfo == null) ? null :
(applicationForm.employeeInfo.workingConditions == null) ? null :
applicationForm.employeeInfo.workingConditions.salary;
If you just want to know whether or not it is null:
bool hasSalary = (applicationForm.employeeInfo == null) ? false :
(applicationForm.employeeInfo.workingConditions == null) ? false :
(applicationForm.employeeInfo.workingConditions.salary != null);
Here's my simple solution:
if (applicationForm?.employeeInfo?.workingConditions?.salary != null)
Here any of these objects (applicationForm, employeeInfo, workingConditions, salary) can be null and it will resolve without error.
can't you iterate?
for (SomeObject obj = someInstance; obj != null; obj = obj.Parent) {
//do something
}
Use reflection.
Create a helper method that takes a parent object and a hierarchical dot notated string for your property names. Then use PropertyInfo and use recursion to go down one property at a time each time checking for null and returning null if so, else continuing down the hierarchy.
Since you didn't provide all too many details I had to fill in alot of the blanks. Here is a psuo-codeish example of how you might accomplish this via recursion
public bool doesHierarchyContainANull(MyObject ParentObject)
{
if (ParentObject.getMemberToCheckForNull() == null)
return true;
else if (ParentObject.isLastInHierarchy())
return false;
return doesHierarchyContainANull(ParentObject.getNextInHierarchy());
}
I liked the answer by Pontus Bremdahl, but added some more detail for my uses.
Code:
/// <summary>
/// Get a member in an object hierarchy that might contain null references.
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source">Base object to get member from.</param>
/// <param name="getResult">Member path.</param>
/// <param name="defaultResult">Returned object if object hierarchy is null.</param>
/// <returns>Default of requested member type.</returns>
public TResult SafeGet<TSource, TResult>(TSource source, Func<TSource, TResult> getResult, TResult defaultResult)
{
// Use EqualityComparer because TSource could by a primitive type.
if (EqualityComparer<TSource>.Default.Equals(source, default(TSource)))
return defaultResult;
try
{
return getResult(source);
}
catch
{
return defaultResult;
}
}
/// <summary>
/// Get a member in an object hierarchy that might contain null references.
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source">Base object to get member from.</param>
/// <param name="getResult">Member path.</param>
/// <returns>Default of requested member type.</returns>
public TResult SafeGet<TSource, TResult>(TSource source, Func<TSource, TResult> getResult)
{
// Use EqualityComparer because TSource could by a primitive type.
if (EqualityComparer<TSource>.Default.Equals(source, default(TSource)))
return default(TResult);
try
{
return getResult(source);
}
catch
{
return default(TResult);
}
}
Usage:
// Only authenticated users can run this code
if (!HttpContext.Current.SafeGet(s => s.User.Identity.IsAuthenticated))
return;
// Get count limit from app.config
var countLimit = int.Parse(ConfigurationManager.AppSettings.SafeGet(
s => s.Get("countLimit"),
"100" // Default 100 if no value is present
));
// Is int 6 a class? Always no, but just to show primitive type usage.
var is6AClass = 6.SafeGet(i => i.GetType().IsClass);
Update
CSharp version 6 now has this built into it.
https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#null-conditional-operators
Null-conditional operators
Sometimes code tends to drown a bit in null-checking. The null-conditional operator lets you access members and elements only when the receiver is not-null, providing a null result otherwise:
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0]; // null if customers is null
The null-conditional operator is conveniently used together with the null coalescing operator ??:
int length = customers?.Length ?? 0; // 0 if customers is null
The null-conditional operator exhibits short-circuiting behavior, where an immediately following chain of member accesses, element accesses and invocations will only be executed if the original receiver was not null:
int? first = customers?[0].Orders.Count();
This example is essentially equivalent to:
int? first = (customers != null) ? customers[0].Orders.Count() : null;
Except that customers is only evaluated once. None of the member accesses, element accesses and invocations immediately following the ? are executed unless customers has a non-null value.
Of course null-conditional operators can themselves be chained, in case there is a need to check for null more than once in a chain:
int? first = customers?[0].Orders?.Count();
Note that an invocation (a parenthesized argument list) cannot immediately follow the ? operator – that would lead to too many syntactic ambiguities. Thus, the straightforward way of calling a delegate only if it’s there does not work. However, you can do it via the Invoke method on the delegate:
if (predicate?.Invoke(e) ?? false) { … }
We expect that a very common use of this pattern will be for triggering events:
PropertyChanged?.Invoke(this, args);
This is an easy and thread-safe way to check for null before you trigger an event. The reason it’s thread-safe is that the feature evaluates the left-hand side only once, and keeps it in a temporary variable.
CheckForNull(MyType element)
{
if(element.ChildElement != null)
{
CheckForNull(element.ChildElement);
}
else
{
Console.WriteLine("Null Found");
}
}
You need a recursive function to iterate through the structure and check each node and its children for null. I was working on a sample but IE crashed (typical!!). Will post one later.
Sample
You could do something as simple (assuming you only ever want to just check if the structure is valid) as this:
public void ValidateStructure()
{
Node root = // get the root node
try
{
ValidateChildren(root);
Console.WriteLine("All nodes are valid");
}
catch (NullReferenceException)
{
Console.WriteLine("Structure contained a null node.");
}
}
public void ValidateChildren(Node parent)
{
// an NullReferenceException would be raised here since parent would be null
foreach (var child in parent.Children)
{
ValidateChildren(child);
}
}
My solution would be something like:
public static TResult SafeGet<TSource, TResult>(this TSource source, Func<TSource, TResult> getResult) {
if (source == null)
return default(TResult);
try {
return getResult(source);
}
catch {
return default(TResult);
}
}
Usage:
Test myTestObject = null;
var myStringOrNull = myTestObject.SafeGet(x => x.test.test.test.mySring);
Use the Null monad. It can be in the same file or a different file so long as you using it.
public static class NullMonad {
public static TResult SelectMany<TIn, TOut, TResult>(this TIn #in, Func<TIn, TOut> remainder, Func<TIn, TOut, TResult> resultSelector)
where TIn : class
where TOut : class
where TResult : class {
var #out = #in != null ? remainder(#in) : null;
return #out != null ? resultSelector(#in, #out) : null;
}
}
Then you can use LINQ:
var salary = from form in applicationForm
from info in form.employeeInfo
from cond in info.workingConditions
select cond.salary
This will return the salary if it exists, or null if any of the prior statements result to null, without throwing an exception.
Is it that much better? No, just saves you the slightest bit of repetition, but it looks cool. It also avoids the overhead of creating all the unused "OrDefault" objects in the accepted answer.