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

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;
}
}

Related

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.

'?' in middle of LINQ statement

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.

Is there a way to Imitate C# 6 Null-Conditional operator in C# 5

I have a situation where I need to assign some objects' properties inside an object initializer. Some of these objects can be null and I need to access their properties, the problem is that they are too many, and using a if/else thing is not good.
Example
visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV()
{
VisiteId = joined.Visite.VisiteId.ToString(),
NomPointDeVente = joined.VisitePdvProduit.PointDeVente.NomPointDeVente,
});
The joined.VisitePdvProduit can be null, and the problem is that there are like dozens of such assignments (I just took one to shorten the code)
The C# 6 Null-Conditional operator is the perfect solution for this situation, the problem is that I'm on C# 5 in this project, is there a way to imitate that ?
Well, you can use an extension method that receives an accessor delegate and only executes it if the item isn't null:
public static TResult ConditionalAccess<TItem, TResult>(this TItem item, Func<TItem, TResult> accessor) where TResult : Class
{
if (item == null)
{
return null;
}
else
{
return accessor(item);
}
}
You can use it for example like this:
NomPointDeVente = joined.VisitePdvProduit.ConditionalAccess(_ => _.PointDeVente.NomPointDeVente);
You can easily create versions of this method for operations that don't return a value (i.e. bar.ConditionalAccess(_ => _.Foo())) or return value types.
Like this. Ugly, but what had to be done.
visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV()
{
VisiteId = joined.Visite.VisiteId.ToString(),
NomPointDeVente = (joined.VisitePdvProduit == null) ? null : joined.VisitePdvProduit.PointDeVente.NomPointDeVente,
});
If you are talking about the semi-very surprised operator ?., then no. There's no way to mimic the syntax.
What you can do, though, is to create an extension method (or a helper method, static one, preferably) or an instance method working with the properties.
Or, as someone suggested, just use the conditional statement (inline or explicit). But that's not what you're looking for, of course.
One more method (and it's not at all recommendable) is to surround the assignment with a try-catch. But that's really baaad solution and I only mention it for completeness' sake.

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.

Refactor help c#

I have several hundred lines of code like this:
if (c.SomeValue == null || c.SomeProperty.Status != 'Y')
{
btnRecordCall.Enabled = false;
}
if (c.SomeValue == null || (c.SomeProperty.Status != 'Y' &&
c.SomeOtherPropertyAction != 'Y'))
{
btnAddAction.Enabled = false;
}
if (c.SomeValue == null || c.SomeProperty.Processing != 'Y')
{
btnProcesss.Enabled = false;
}
How can I refactor this correctly? I see that the check 'c.SomeValue == null' is being called every time, but it is included with other criteria. How can I possibly eliminate this duplicate code?
I would use the specification pattern, and build composite specifications that map to a proper Enabled value.
The overall question you want to answer is whether some object c satisfies a given condition, which then allows you to decide if you want something enabled. So then you have this interface:
interface ICriteria<T>
{
bool IsSatisfiedBy(T c);
}
Then your code will look like this:
ICriteria<SomeClass> cr = GetCriteria();
btnAddAction.Enabled = cr.IsSatisfiedBy(c);
The next step is to compose a suitable ICriteria object. You can have another ICriteria implementation, (in additon to Or and And), called PredicateCriteria which looks like this:
class PredicateCriteria<T> : ICriteria<T>
{
public PredicateCriteria(Func<T, bool> p) {
this.predicate = p;
}
readonly Func<T, bool> predicate;
public bool IsSatisfiedBy(T item) {
return this.predicate(item);
}
}
One instance of this would be:
var c = new PredicateCriteria<SomeClass>(c => c.SomeValue != null);
The rest would be composition of this with other criteria.
If you don't want to do much refactoring, you can easily pull the null check out.
if (c.SomeValue == null)
{
btnRecordCall.Enabled = false;
btnAddAction.Enabled = false;
btnProcesss.Enabled = false;
}
else
{
if(c.SomeProperty.Status != 'Y')
{
btnRecordCall.Enabled = false;
}
if((c.SomeProperty.Status != 'Y') &&
(c.SomeOtherPropertyAction != 'Y'))
{
btnAddAction.Enabled = false;
}
if(c.SomeProperty.Processing != 'Y')
{
btnProcesss.Enabled = false;
}
}
If you're looking to refactor instead of shuffle, the wall of boolean testing could be moved in to methods/extension methods of whatever class your object c is an instance of - that way you could say
btnRecordCall.Enabled = c.IsRecordCallAllowed();
Create properties on "c" such as "CanRecordCall", "CanAddAction", "CanProcess" so that your code becomes this:
btnRecordCall.Enabled = c.CanRecordCall;
btnAddAction.Enabled = c.CanAddAction;
btnProcess.Enabled = c.CanProcess;
The "c.SomeValue == null" is a typical response to NullReferenceExceptions. You could improve "c" by initializing its SomeValue property to a null object so that there is never a null reference (just an object that does nothing).
In specific, since you seem to be setting UI elements state, you could consider more of a two-way data binding model where you set up a data context and a control-to-property mapping and let that govern the control state. You can also consider a more heavy-weight solution that would be something like the Validation Application Block from Enterprise Library. There are also some fluent validation projects that you should take a look at.
I'd start by making sure all such code is contiguous. Anything other than this code should be moved before or after the code.
Then, for each reference to a control property, create a corresponding local variable, e.g., processEnabled. Define it before the first if statement. For each such property, move, e.g., btnProcesss.Enabled = false; to the end of this code block, and change "false" to processEnabled. Replace the original with processEnabled = false;.
When the code block has no more references to controls (or to anything else having to do with the UI), select the entire block, from the added variables to the control property sets at the end, and use the Extract Method refactoring. That should leave you with a method that accepts c, and produces values you can later use to set control properties.
You can even get fancier. Instead of individual local variables, define a class that has those "variables" as properties. Do pretty much the same thing, and the extracted method will wind up returning an instance of that class, instead of individual out parameters.
From there, you may start to see more things to clean up in the extracted method, not that you'll have removed anything to do with UI from that code.
I'm guessing the issue here is about 'boolean map' style refactorings, i.e., being able to refactor complementary boolean cases where there might be some gaps and some repetition. Well, if that's what you're after, you can certainly write a tool to do this (it's what I would do). Basically, you need to parse a bunch of if statements and take note of condition combinations that are involved. Then, through some fairly simple logic, you can get your model to spit out a different, more optimized model.
The code you show above is one reason why I love F#. :)
Interestingly, in our current Winforms app, the three conditions would be in three different classes, since each button would be attached to a different Command.
The conditions would be in the CanExecute methods of the commands and control the enable/disable behaviour of the button that triggers the command. The corresponding execution code is in the Execute method of the class.

Categories

Resources