Totally unexplainable NullReferenceException - c#

Ok, so I very sporadically get a NullReferenceException on this line of code:
if (!_oracleTenantSettings.OraclePlanSettings.ContainsKey(_key) || _oracleTenantSettings.OraclePlanSettings[_key] == null)
and/or this line:
_oraclePlanSettings = _oracleTenantSettings.OraclePlanSettings[_key];
where OraclePlanSettings is a SortedList, and it can't be null, because the code in question is surrounded by:
if (_oracleTenantSettings.OraclePlanSettings != null && _oracleTenantSettings.OraclePlanSettings.Count > 0)
So I'm getting a NRE, but there is not a single part of the entire line of code that could ever possibly be null, ever. Period. (sense the frustration?) And that includes the key, but that wouldn't throw a NRE anyway. I do not understand. Is it possible that VS is just misplacing the CLR exception? If so, where would be a good place to start looking?
The stack trace is just a one-liner:
at company.product.Mvc.OracleSettingsStoreCache.VerifyValueInCacheOrInsert[T](T& returnVal, SettingsType settingType, String tenantId, String planId, String pageMnemonic, String processId, String transcationType, String language, String country, String wapTransactionType, String wapCodeGroup, String wapLoanReasons, String palleteType, Boolean isInsert, Object _cacheValue) in blahblahblah.OracleSettingsStoreCache.cs:line 290
Here is the entire block of code:
if (!string.IsNullOrEmpty(tenantId) && (!IsWacMode() || (IsWacMode() && settingType == OracleSettingsType.SettingsType.FetchWAPInvestmentTransfer)) && _useCache != "false")
{
tenantId = tenantId.ToUpper().Trim();
_oracleTenantSettings = null;
if (_oracleCacheManager.Contains(_cacheKey))
_oracleTenantSettings = _oracleCacheManager.Get<OracleTenantSetting>(_cacheKey);
if (_oracleTenantSettings != null)
{
if (_oracleTenantSettings.OraclePlanSettings != null && _oracleTenantSettings.OraclePlanSettings.Count > 0)
{
_key = language + "_" + country + "_" + tenantId;
***LINE 290*** if (!_oracleTenantSettings.OraclePlanSettings.ContainsKey(_key) || _oracleTenantSettings.OraclePlanSettings[_key] == null)
{
_objectMissing = TypeOfObjectMissing.TenantObjectDoesNotExist;
}
}

Without seeing the context that code lives within, it's hard to be sure. But based on the symptoms you describe, i.e. very sporadic...inexplicable...something's null that can't be... I would strongly suspect a threading issue. For example, if the collection is static and potentially accessed by multiple threads, it can happen (although it's a rare occurrence of chance timing) that a second thread modifies the collection contents between when the first thread tests if something is there and when it accesses that something.
If that's the case, you must make your code more threadsafe. You can use lock or concurrent collections to avoid this problem. To use lock, you need to use a synchronization object (not a new object created on the fly). You would also want to hunt up ALL places where that collection is accessed, and surround every one with a lock...code that just looks at the collection must use lock as well as code that modifies the collection. This is a big topic for a SO answer, so I would recommend you use this really great resource:
http://www.albahari.com/threading/
Here is how you could get NREs in this case:
thread 1 checks if entry exists in SortedList myList for _key="hello"
gets true
thread 1 checks if entry for _key="hello" is non-null
gets true
thread 2 sets myList["hello"] = null
thread 1 executes myList["hello"].Something() and gets NRE.
Based on the edits to your post, it seems that in these lines
if (_oracleTenantSettings != null) {
if (_oracleTenantSettings.OraclePlanSettings != null && _oracleTenantSettings.OraclePlanSettings.Count > 0) {
_key = language + "_" + country + "_" + tenantId;
if (!_oracleTenantSettings.OraclePlanSettings.ContainsKey(_key) || _oracleTenantSettings.OraclePlanSettings[_key] == null)
if the NRE occurs on the last line, then right after executing the first line or second line, another thread can either set _oracleTenantSettings or _oracleTenantSettings.OraclePlanSettings to null. Either of those things happening would cause the final line to throw an NRE.
The following code is not the proper way to make your code thread safe, but might serve as a quick way to see if this is indeed the case since it would make this situation (the null reference exception) less likely:
var oracleTS = _oracleTenantSettings;
if (oracleTS != null) {
var planSettings = oracleTS.OraclePlanSettings;
if ((planSettings != null) && (planSettings.Count > 0)) {
_key = language + "_" + country + "_" + tenantId;
if (!planSettings.ContainsKey(_key) || planSettings[_key] == null)
Note that the final line could still have other issues related to threading like the key being removed by another thread between the first part of the conditional and the second part, or planSettings Count changing after being tested. But if this code drastically reduces the NREs, then you have a pretty good clue what was happening, and that you should go through and properly make your code thread safe with locks where needed. To say further, a person would need to know more about what other code is doing, especially code that modifies _oracleTenantSettings.

My guess is that there is another thread accessing the property.
A quick way to fix it would be locking on it every time you access it like this:
var oraclePlanSettings = _oracleTenantSettings.OraclePlanSettings;
lock (oraclePlanSettings)
{
// from now on you can safely access your cached reference "oraclePlanSettings"
if (oraclePlanSettings != null && oraclePlanSettings.Count > 0)
_oraclePlanSettings = oraclePlanSettings[_key]; // ... blabla
}
Beware of deadlocks tho.

I agree with the previous answers, It's probably a threading issue, but I have someting to add.
Here is a quick and dirty test to determine if it's threading or not.
Set up a scenerio that reproduces the error (say running it in several (10) threads in a constant loop overnight)
Apply this attribute to your class
[Synchronization]
Your Class must inherit from ContextBoundObject.
That forces all the instances of the class to run on a single thread (way slower).
Re run your test.
If your problem goes away, you have a threading issue. If speed is a concern, you need to go back and do all the locking around the code that touches that object. If you convert everything to use properties for the objects in question you can just lock the getter and setter.
If the quick and dirty test fails to fix the issue, it's probabaly something else. For instance if you're using unsafe code or unsafe dlls (ie stuff written in non .Net c++), it might be a memory corruption problem.
Hope this helps.
Here is more detail on the attribute, including inheriting from ContextBoundObject.
Ms Docs
Code sample:
// Context-bound type with the Synchronization context attribute.
[Synchronization()]
public class SampleSynchronized : ContextBoundObject {
// A method that does some work, and returns the square of the given number.
public int Square(int i) {
Console.Write("The hash of the thread executing ");
Console.WriteLine("SampleSynchronized.Square is: {0}",
Thread.CurrentThread.GetHashCode());
return i*i;
}
}

Update
I am proposing that somewhere in the code the Equality operator or the == has been overloaded on one of the related objects and the failure occurs when either null is not be checked for properly (or fails) or something is returned as equal when it is not.
Check for all operator overloads on == for any class object being used in this situation and rectify..
Original
Change the logic to this, for you want to first check for no key...THEN..do the check when there is a valid key but (and) its value is null:
if ((_oracleTenantSettings.OraclePlanSettings.ContainsKey(_key) == false) ||
((_oracleTenantSettings.OraclePlanSettings.ContainsKey(_key)) &&
_oracleTenantSettings.OraclePlanSettings[_key] == null)))
Its actually expected if you think through the logic flow of the original statements why it intermittently fails. :-)
EDIT:
Let me explain, Follow this logic by steps
In the original if clause when it evaluates the (!ContainsKey(_key)) means that when the key is NOT there (true) it gets changed to FALSE.
Then the Or kicks in because of False in #1. It evaluates the OraclePlanSettings[_key] BUT the key is not there right?
So it executes code to check on null for an invalid key and throws an exception.
Only by breaking out the logic as I have shown, will the excpetion not be thrown.

Related

Unity code with rare null reference that I can't figure out

I have a simple function in my Unity game code where I am looking for a "work spot" - an empty place for my NPCs to do some task.
This code works perfectly well 99.999% of the time, but throws a NULL REFERENCE EXCEPTION very occasionally and I can't for the life of me figure out where. I have tried to catch every possible place where something could be unassigned and can't find it. There must be some edge case I am missing, or something in my code that misbehaves under some strange circumstances.
So my code is flawed and I don't understand where. Help me improve it:
public Transform[] workSpots;
public Transform findAvailableWorkSpot() {
if (workSpots == null || workSpots.Length == 0) return null; // sometimes we have no work spots
int i=0;
while (i<10) {
Transform spot = workSpots[Random.Range(0, workSpots.Length)];
if (spot != null && spot.childCount == 0) {
return spot;
}
i++;
}
// couldn't find one randomly, let's just iterate over them:
foreach (Transform spot in workSpots) {
if (spot != null && spot.childCount == 0) {
return spot;
}
}
Debug.LogError("could not find free workspot on "+gameObject.name);
return null;
}
Logic:
first, try up to 10 times to get a free random work spot. I parent the NPC to the work spot when he is working there, so spot.childCount == 0 is true if the spot has no NPC on it right now.
if that fails, then I just iterate over all of them and pick the first free one.
it is ok to return null here, the calling code will handle that
The Diagnostic backend tells me that 2-4 times a day someone experiences a Null Reference Exception in this function, but diagnostics doesn't tell me the line number and I've never seen it locally. I'm looking at it again and again and I can't spot where it could be. Maybe something more fundamental is wrong with my code?
Additional Information:
workspots is initialized in Awake() and is never again changed, so I am sure that the test at the beginning of the function works and it's not possible that it goes to null while the function is running.
This is not directly an answer to where exactly the exception comes from.
But if you are open to using Linq you can simplyfy your code a lot!
I would simply use
using System.Linq;
...
public Transform[] workSpots;
public bool TryFindAvailableWorkSpot(out Transform freeSpot)
{
// First heck this component even is alive
if (!this || workSpots == null || workSpots.Length == 0)
{
freeSpot = null;
return false;
}
// First "Where" filters out only those spots that exist and have no children
// then "OrderBy" randomizes these results
// then we take the first one or null if there isn't any
freeSpot = workSpots.Where(spot => spot && spot.childCount == 0).OrderBy(spot => Random.value).FirstOrDefault();
// use the implicit bool operator for checking if we have found a valid reference
return freeSpot;
}
and then instead of using
var spot = yourClass.findAvailableWorkSpot();
and having to again check for null and potential exceptions you would rather simply do the check in the same line using e.g.
if(yourClass.TryFindAvailableWorkSpot(out var spot))
{
... Do someting with spot
}
else
{
Debug.LogError("could not find free workspot");
}
See
Linq Where
Linq OrderBy
Random.value
Linq FirstOrDefault
Unityengine.Object implicit bool operator
I don't think you are looking at the right place where the exception happened. The way you've written the code it's just not possible for workSpots to be null or empty.
The only places where I can see a null reference exception happening is if you are trying to access workSpots[index] -> and that returns a Transform object that is null and you try using it (but in your code you are prepared for that).
Maybe the places where you use that particular method do not check if the Transform that you are returning is null before trying to access it.
If your code is well written and you don't believe it then the null reference exception is probably caused by gameObject.name when trying to log an error. If it isn't that then I have no idea honestly.

Do references to collections cause any trouble with threads?

I have something like the following code:
public class MainAppClass : BaseClass
{
public IList<Token> TokenList
{
get;
set;
}
// This is execute before any thread is created
public override void OnStart()
{
MyDataBaseContext dbcontext = new MyDataBaseContext();
this.TokenList = dbcontext.GetTokenList();
}
// After this the application will create a list of many items to be iterated
// and will create as many threads as are defined in the configuration (5 at the momment),
// then it will distribute those items among the threads for parallel processing.
// The OnProcessItem will be executed for every item and could be running on different threads
protected override void OnProcessItem(AppItem processingItem)
{
string expression = getExpressionFromItem();
expression = Utils.ReplaceTokens(processingItem, expression, this);
}
}
public class Utils
{
public static string ReplaceTokens(AppItem currentProcessingItem, string expression, MainAppClass mainAppClass)
{
Regex tokenMatchExpression = new Regex(#"\[[^+~][^$*]+?\]", RegexOptions.IgnoreCase);
Match tokenMatch = tokenMatchExpression.Match(expression)
if(tokenMatch.Success == false)
{
return expression;
}
string tokenName = tokenMatch.Value;
// This line is my principal suspect of messing in some way with the multiple threads
Token tokenDefinition = mainAppClass.TokenList.Where(x => x.Name == tokenName).First();
Regex tokenElementExpression = new Regex(tokenDefintion.Value);
MyRegexSearchResult evaluationResult = Utils.GetRegexMatches(currentProcessingItem, tokenElementExpression).FirstOrDefault();
string tokenValue = string.Empty;
if (evaluationResult != null && evaluationResult.match.Groups.Count > 1)
{
tokenValue = evaluationResult.match.Groups[1].Value;
}
else if (evaluationResult != null && evaluationResult.match.Groups.Count == 1)
{
tokenValue = evaluationResult.match.Groups[0].Value;
}
expression = expression.Replace("[" + tokenName + "]", tokenValue);
return expression;
}
}
The problem I have right now is that for some reason the value of the token replaced in the expression get confused with one from another thread, resulting in an incorrect replacement as it should be a different value, i.e:
Expression: Hello [Name]
Expected result for item 1: Hello Nick
Expected result for item 2: Hello Sally
Actual result for item 1: Hello Nick
Actual result for item 2: Hello Nick
The actual result is not always the same, sometimes is the expected one, sometimes both expressions are replaced with the value expected for the item 1, or sometimes both expressions are replaced with the value expected for the item 2.
I'm not able to find what's wrong with the code as I was expecting for all the variables within the static method to be in its own scope for every thread, but that doesn't seem to be the case.
Any help will be much appreciated!
Yeah, static objects only have one instance throughout the program - creating new threads doesn't create separate instances of those objects.
You've got a couple different ways of dealing with this.
Door #1. If the threads need to operate on different instances, you'll need to un-static the appropriate places. Give each thread its own instance of the object you need it to modify.
Door #2. Thread-safe objects (like mentioned by Fildor.) I'll admit, I'm a bit less familiar with this door, but it's probably the right approach if you can get it to work (less complexity in code is awesome)
Door #3. Lock on the object directly. One option is to, when modifying the global static, to put it inside a lock(myObject) { } . They're pretty simple and straight-foward (so much simpler than the old C/C++ days), and it'll make it so multiple modifications don't screw the object up.
Door #4. Padlock the encapsulated class. Don't allow outside callers to modify the static variable at all. Instead, they have to call global getters/setters. Then, have a private object inside the class that serves simply as a lockable object - and have the getters/setters lock that lockable object whenever they're reading/writing it.
The tokenValue that you're replacing the token with is coming from evaluationResult.
evaluationResult is based on Utils.GetRegexMatches(currentProcessingItem, tokenElementExpression).
You might want to check GetRegexMatches to see if it's using any static resources, but my best guess is that it's being passed the same currentProcessingItem value in multiple threads.
Look to the code looks like that splits up the AppItems. You may have an "access to modified closure" in there. For example:
for(int i = 0; i < appItems.Length; i++)
{
var thread = new Thread(() => {
// Since the variable `i` is shared across all of the
// iterations of this loop, `appItems[i]` is going to be
// based on the value of `i` at the time that this line
// of code is run, not at the time when the thread is created.
var appItem = appItems[i];
...
});
...
}

RowNotInTableException being thrown for DataTable when it shouldn't?

I'm not sure why this exception is happening... I could understand if I wasn't checking for i < table.Rows.Count but I do check for this, so I am confused as to why the row is not in the table... I've hit a roadblock here and could use someone a little more experienced with this problem than me. I just hope it's one of those small stupid mistakes.
Edit: Earlier on I had a debug line myTable.Rows[0]["FieldName"] and myTable.Rows[1]["FieldName"]. The second one threw the exception as well, the first did not.
internal Collection<fieldDef> DefaultList
{
get
{
Collection<fieldDef> listFields = new Collection<fieldDef>();
listFields.Clear();
//Rows.Count is checked here, which is why I'm so confused...
for (int i = 0; i < myTable.Rows.Count; i++)
{
string strFieldName = "";
if (myTable.Rows[i]["FieldName"].ToString() != "") //Exception happens here
{
strFieldName = myTable.Rows[i]["FieldName"].ToString();
}
FieldType type = FieldType.Character;
if (myTable.Rows[i]["FieldType"].ToString() != "") type = (FieldType)Enum.Parse(typeof(FieldType), myTable.Rows[i]["FieldType"].ToString());
//
//Other Similar lines to that above
//
fieldDef def = new fieldDef(i, strFieldName, strFieldName, type, /*other items...*/);
listFields.Add(def);
}
return listFields;
}
set
{
//Nothing negative happens here, left out for simplicity
}
}
I found the solution. Just posting in case anyone has the same problem. It's not stated in the original post, but this is called via change/edit events on the DataTable (which are triggered by button clicks and required to save settings).
The issue is that if you try to get the property within the event, the row is actually pulled from the table (like when it is being moved up or down) and the state is "detached", therefore, no longer officially in the table.
To solve this, I simply waited to access my property until after the event had completely finished (thus the row being fully placed back into the table) which required a little reworking of other parts of my code.
Hope this helps someone down the road!
I don't have the 50 rep yet to be able to comment/ask questions, so my answer is based on what I am seeing above...
To start, it would be helpful if you included what your error/exception is. That said, while you may have a row, you are not checking for null when calling the FieldName field in that row--are you sure you have a non-null value in that field, in that row? If it is null, calling .ToString() will throw an exception...I would suggest something like this:
if (myTable.Rows[i]["FieldName"] != null && myTable.Rows[i]["FieldName"].ToString() != "") //Exception happens here
{
strFieldName = myTable.Rows[i]["FieldName"].ToString();
}
This may or may not be your issue, but either way, checking for null here would be good practice and help avoid invalid operations such as trying to a null instance.

C# IF statements, and doing things very specifically from which is true

So, to start, I have seen posts like this: How to find which condition is true without using if statement
It's not quite what I need, although the idea is pertinent, in that I would like it to be more readable code.
I think Switch is the best bet, but let me explain.
I have this statement:
if (input == string.Empty || typeComboBox.Text == null)
{
MessageBox.Show("Nothing to encrypt!", "Nothing Selected!");
return null;
}
So the idea here is that I used to have this statement broken into two "IF" statements, which isn't a huge deal, but for readability sake, and my on going effort of reducing code, I wanted to combine the statements into one.
If input is empty, I want the first argument in MessageBox.Show to appear, but not the second.
If typeComboBox.Text is null, I want the second option to appear, but not the first.
If they are both true statements, I want both to appear.
Now, my goal was to have these both done without the use of more than one test or method. Basically, I mean this: if I can find which condition is true and have the resultant data output within the same statement, that would be ideal.
I see switches being an option, and I don't understand them very well yet, but I think that would require me to make a decision method based on the outcome of this test, and send that outcome to the switch; which wouldn't be ideal, as I could simply have two if statements and less code.
Is there any way to do this in one statement? It's not necessary for this specific program, but I want to know for the future.
Thanks!
I am assuming that you started with this code:
if (input == string.Empty)
{
MessageBox.Show("Nothing to encrypt!");
return null;
}
if (typeComboBox.Text == null)
{
MessageBox.Show("Nothing Selected!");
return null;
}
I don't consider there to be anything wrong with this code at all, and this is probably the most readable. It will perform exactly as many tests as necessary, and no more. Any alternative will result in more tests being performed, even though you may wind up with less code. For example:
if (input == string.Empty || typeComboBox.Text == null)
{
MessageBox.Show((input == string.Empty) ? "Nothing to encrypt!" : "Nothing Selected!");
return null;
}
Less lines of code, but in a failure scenario there will be two or three tests performed instead of one or two. It's also a bit less straightforward.
Terse code is nice, but make it too terse and it becomes harder to maintain. Readability lies somewhere between verbose and terse, and in this case the more verbose code is more readable, in my opinion.
Another option is to consider the fact that it would be appropriate to report multiple errors. For that, try code like this:
List<string> errors = new List<string>();
if (input == string.Empty)
{
errors.Add("Nothing to encrypt.");
}
if (typeComboBox.Text == null)
{
errors.Add("Nothing selected.");
}
if (errors.Count != 0)
{
MessageBox.Show(string.Join(" ", errors.ToArray()));
return null;
}
This is a bit more verbose than your original code, but it will allow all relevant errors to be reported instead of only the first one encountered.
#millimoose's comment is right on; two if statements would be the cleanest thing for your code. However, if you're wanting to expand your validations to a large number or establish a general pattern for validations of this sort, you could do something like set up a validation table:
public class ValidationRule
{
public ValidationRule(Func<bool> test, string errorMessage)
{
this.Test = test;
this.ErrorMessage = errorMessage;
}
public Func<bool> Test { get; private set; }
public string ErrorMessage { get; private set; }
}
var validationRules = new[] {
new ValidationRule(() => input != string.Empty, "Nothing to encrypt!"),
new ValidationRule(() => typeComboBox.Text != null, "Nothing Selected!")
};
With a table like this, you could then have code like this:
var errors = validationRules.Where(r => !r.Test()).Select(r => r.ErrorMessage);
if (errors.Any())
{
MessageBox.Show(string.Join(' ', errors));
return null;
}
If, however, you're only looking for something for your two conditions, then this is over-engineering.
I'd suggest a slightly different pattern that might be more readable:
StringBuilder message = new StringBuilder();
if (input == string.Empty) message.Append("Nothing to encrypt!\n");
if (typeComboBox.Text == null) message.Append("Nothing selected!\n");
// ... repeat as many times as desired ...
if (message.Length > 0) {
MessageBox.Show(message);
return null;
} else {
// proceed with your code here
}
This code has the advantage that it can show multiple messages, if more than one is valid. It can be frustrating for a user to see only one message at a time, if they have to go back, fix something, hit submit, and see a different error message.
There isn't a way in code to have three (seemingly) different actions decided by a single logical statement. If you try to break it down to the simplest logical (not in code, but just mental logic) flow you still end up with something like:
If A is true then do B
If C is true then do D
If both A and C is true do B and D
That can be simplified by noting (as you did) that each condition is actually separate from the other:
If A is true then B is always done
If C is true then D is always done
So, in your code, the simplest breakdown is
if (input == string.empty)
{
// Do some stuff
}
if (typeComboBox.Text == null)
{
// Do some other stuff
}
Now, rather than have a long complicated set of instructions on either method - you can simplify the look of your code by making this simply a decision section, that calls other methods to do the work:
if (input == string.empty)
{
this.PrimeInputs(); // or something
}
if (typeComboBox.Text == null)
{
this.InitTextBoxes(); // or something
}
The main thing is, this is different than a logical AND and logical OR since you want one action or the other - in some cases, and neither action if both cases are false, and both actions if both cases are true.
I wouldn't say this is better than a couple "if" statements, but it is only one.
var message =
((input==string.Empty ?
"Nothing to encrypt! " :
"") +
(typeComboBox.Text == null ?
"Nothing Selected!" :
"")).Trim();
if (message != "") {
MessageBox.Show(message);
return null;
}
Generally speaking, though, I like using conditional operators to construct logic trees that result in a single outcome, it's much more terse than a bunch of nested if/else clauses. As long as you indent properly I find such structures highly readable and expressive. Unfortunately in this case it's not ideal because you have outcomes that depend on combinations of your operands. Using this kind of logic to build a string probably isn't the best idea, though it is still probably the most terse option.

Is it acceptable to only use the 'else' portion of an 'if-else' statement?

Sometimes, I feel like it is easier to check if all of the conditions are true, but then only handle the "other" situation.
I guess I sometimes feel that it is easier to know that something is valid, and assume all other cases are not valid.
For example, let's say that we only really care about when there is something wrong:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop)))
{
// All the conditions passed, but we don't actually do anything
}
else
{
// Do my stuff here, like error handling
}
Or should I just change that to be:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop)))
{
// Do my stuff here, like error handling
}
Or (which I find ugly):
object value = GetValueFromSomeAPIOrOtherMethod();
if(!((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop))))
{
// Do my stuff here, like error handling
}
Though rare for me, I sometimes feel that writing in this form leads to the clearest code in some cases. Go for the form that provides the most clarity. The compiler won't care, and should generate essentially (probably exactly) the same code.
It may be clearer, though, to define a boolean variable that is assigned the condition in the if () statement, then write your code as a negation of that variable:
bool myCondition = (....);
if (!myCondition)
{
...
}
Having an empty if block with statements in the else is ... just bad style. Sorry, this is one of my pet peeves. There is nothing functionally wrong with it, it just makes my eyes bleed.
Simply ! out the if statement and put your code there. IMHO it reduces the noise and makes the code more readable.
I should preface this by saying that it's my own personal preference, but I find myself usually pulling the validation logic out of the code and into its own validate function. At that point, your code becomes much "neater" by just saying:
if(!ValidateAPIValue(value))
That, in my mind, seems a lot more concise and understandable.
Just using the else part isn't acceptable. You needn't go to the trouble of applying De-Morgan's rule, just not the whole expresssion. That is, go from if (cond) to if (!(cond)).
I think it's completely unacceptable.
The only reason at all would be to avoid a single negation and pair of parentheses around the expression. I agree that the expressions in your example are horrible, but they are unacceptably convoluted to begin with! Divide the expression into parts of acceptable clarity, store those into booleans (or make methods out of them), and combine those to make your if-statement condition.
One similar design I do often use is exiting early. I don't write code like this:
if (validityCheck1)
{
if (validityCheck2)
{
// Do lots and lots of things
}
else
{
// Throw some exception, return something, or do some other simple cleanup/logic (version 2)
}
}
else
{
// Throw some exception, return something, or do some other simple cleanup/logic. (version 1)
}
Instead I write this:
if (!validityCheck1)
{
// Throw some exception, return false, or do some other simple logic. (version 1)
}
if (!validityCheck2)
{
// Throw some exception, return false, or do some other simple logic. (version 2)
}
// Do lots and lots of things
This has two advantages:
Only a few input cases are invalid, and they have simple handling. They should be handled immediately so we can throw them out of our mental model as soon as possible and fully concentrate on the important logic. Especially when there are multiple validity checks in nested if-statements.
The block of code that handles the valid cases will usually be the largest part of the method and contain nested blocks of its own. It's a lot less cluttered if this block of code is not itself nested (possibly multiple times) in an if-statement.
So the code is more readable and easier to reason about.
Extract your conditions, then call
if(!ConditionsMetFor(value))
{
//Do Something
}
Although this is not always practical, I usually prefer to change
if (complexcondition){} else {/*stuff*/}
to
if (complexcondition) continue;
/*stuff*/
(or break out with return, break, etc.). Of course if the condition is too complex, you can replace it with several conditions, all of which cause the code to break out of what it is doing. This mostly applies to validation and error-checking types of code, where you probably want to get out if something goes wrong.
If I see an "if", I expect it to do something.
if(!condition)
is far more readable.
if(condition) {
//do nothing
}
else {
//do stuff
}
essentially reads, "If my condition is met, do nothing, otherwise do something."
If we are to read your code as prose (which good, self-documenting code should be able to be read in that fashion) that's simply too wordy and introduces more concepts than necessary to accomplish your goal. Stick with the "!".
This is bad style, consider some very useful alternatives:
Use a guard clause style:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop)))
{
return;
}
// do stuff here
Extract the conditional into its own method, this keeps things logical and easy to read:
bool ValueHasProperty(object value)
{
return (value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop));
}
void SomeMethod()
{
object value = GetValueFromSomeAPIOrOtherMethod();
if(!ValueHasProperty(value))
{
// do stuff here
}
}
Your question is similar to my answer(simplifying the conditions) on favorite programmer ignorance pet peeve's
For languages that don't support an until construct, chaining multiple NOTs makes our eyes bleed
Which one is easier to read?
This:
while (keypress != escape_key && keypress != alt_f4_key && keypress != ctrl_w_key)
Or this:
until (keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key)
I am of the opinion that the latter is way easier to grok than the first one. The first one involves far too many NOTs and AND conditions makes the logic more sticky, it forces you to read the entire expression before you can be sure that your code is indeed correct, and it will be far more harder to read if your logic involves complex logic (entails chaining more ANDs, very sticky).
During college, De Morgan theorem is taught in our class. I really appreciate that logics can be simplified using his theorem. So for language construct that doesn't support until statement, use this:
while !(keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key)
But since C don't support parenthesis-less while/if statement, we need to add parenthesis on our DeMorgan'd code:
while (!(keypress == escape_key || keypress == alt_f4_key || keypress == ctrl_w_key))
And that's what could have prompted Dan C's comment that the DeMorgan'd code hurts his eyes more on my answer on favorite programmer ignorance pet peeve's
But really, the DeMorgan'd code is way easier to read than having multiple NOTS and sticky ANDs
[EDIT]
Your code (the DeMorgan'd one):
object value = GetValueFromSomeAPIOrOtherMethod();
if ( value == null || string.IsNullOrEmpty(value.Prop)
|| !possibleValues.Contains(value.prop) )
{
// Do my stuff here, like error handling
}
..is perfectly fine. In fact, that's what most programmers(especially from languages that don't have try/catch/finally constructs from the get-go) do to make sure that conditions are met(e.g. no using of null pointers, has proper values, etc) before continuing with the operations.
Note: I took the liberty of removing superfluous parenthesis on your code, maybe you came from Delphi/Pascal language.
I do it when my brain can easily wrap itself around the logic of the success but it is cumbersome to understand the logic of the failure.
I usually just put a comment "// no op" so people know it isn't a mistake.
This is not a good practice. If you were using ruby you'd do:
unless condition
do something
end
If your language doesn't allow that, instead of doing
if(a){}else{something}
do
if(!a){something}
I find it to be unacceptable (even though I'm sure I've done it in the past) to have an empty block like that. It implies that something should be done.
I see the other questions state that it's more readable the second way. Personally, I say neither of your examples is particularly readable. The examples you provided are begging for an "IsValueValid(...)" method.
I occasionally find myself in a related but slightly different situation:
if ( TheMainThingIsNormal () )
; // nothing special to do
else if ( SomethingElseIsSpecial () ) // only possible/meaningful if ! TheMainThingIsNormal ()
DoSomethingSpecial ();
else if ( TheOtherThingIsSpecial () )
DoSomethingElseSpecial ();
else // ... you see where I'm going here
// and then finish up
The only way to take out the empty block is to create more nesting:
if ( ! TheMainThingIsNormal () )
{
if ( SomethingElseIsSpecial () )
DoSomethingSpecial ();
else if ( TheOtherThingIsSpecial () )
DoSomethingElseSpecial ();
else // ...
}
I'm not checking for exception or validation conditions -- I'm just taking care of special or one-off cases -- so I can't just bail out early.
My answer would usually be no....but i think good programming style is based on consistency.....
so if i have a lot of expressions that look like
if (condition)
{
// do something
}
else
{
// do something else
}
Then an occasional "empty" if block is fine e.g.
if (condition)
{ } // do nothing
else
{
// do something else
}
The reason for this is that if your eyes sees something several times, their less likely to notice a change e.g. a tiny "!". So even though its a bad thing to do in isolation, its far likely to make someone maintaining the code in future realize that this particular if..else... is different from the rest...
The other specific scenerio where it might be acceptable is for some kind of state machine logic e.g.
if (!step1done)
{} // do nothing, but we might decide to put something in here later
else if (!step2done)
{
// do stuff here
}
else if (!step3done)
{
// do stuff here
}
This is clearly highlighting the sequential flow of the states, the steps performed at each (even if its nothing). Id prefer it over something like...
if (step1done && !step2Done)
{
// do stuff here
}
if (step1done && step2done && !state3Done)
{
// do stuff here
}
I like the second version. It makes code more clean. Actually this is one of the things I would ask to correct during the code review.
I always try and refactor out big conditions like this into a property or method, for readability. So this:
object value = GetValueFromSomeAPIOrOtherMethod();
if((value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop)))
{
// Do my stuff here, like error handling
}
becomes something like this:
object value = GetValueFromSomeAPIOrOtherMethod();
if (IsValueUnacceptable(value))
{
// Do my stuff here, like error handling
}
...
/// <summary>
/// Determines if the value is acceptable.
/// </summary>
/// <param name="value">The value to criticize.</param>
private bool IsValueUnacceptable(object value)
{
return (value == null) || (string.IsNullOrEmpty(value.Prop)) || (!possibleValues.Contains(value.prop))
}
Now you can always reuse the method/property if needed, and you don't have to think too much in the consuming method.
Of course, IsValueUnacceptable would probably be a more specific name.
1st:
object value = GetValueFromSomeAPIOrOtherMethod();
var isValidValue = (value != null) && (!string.IsNullOrEmpty(value.Prop)) && (possibleValues.Contains(value.prop));
if(!isValidValue)
{
// Do my stuff here, like error handling
}
2cnd:
object value = GetValueFromSomeAPIOrOtherMethod();
if(!isValidAPIValue(value))
{
// Do my stuff here, like error handling
}
Are all the expressions really the same? In languages that support short-circuiting, making the change between ands and ors can be fatal. Remember &&'s use as a guard to prevent the other conditions from even being checked.
Be careful when converting. There are more mistakes made than you would expect.
In these cases you may wish to abstract the validation logic into the class itself to help un-clutter your application code.
For example
class MyClass
{
public string Prop{ get; set; }
// ... snip ...
public bool IsValid
{
bool valid = false;
if((value != null) &&
(!string.IsNullOrEmpty(value.Prop)) &&
(possibleValues.Contains(value.prop)))
{
valid = true
}
return valid;
}
// ...snip...
}
Now your application code
MyClass = value = GetValueFromSomewhere();
if( value.IsValie == false )
{
// Handle bad case here...
}
I'm a fan of DeMorgan's Rule which takes your ex3 and produces your ex2. An empty if block is a mental block imo. You have to stop to read the nothing that exists - then you have to wonder why.
If you have to leave comments like // This left blank on purpose; then the code isn't very self-explanatory.
The style that follow to have one block empty of if-else is considered as a bad style..
for good programming practice if you dont have to write in if block you need to put (!) 'Not' in if block ..no need to write else
If(condition)
//blank
else
//code
can be replaced as
if(!condition)
//code
this is a saving of extra line of code also..
I wouldn't do this in C#. But I do it in Python, because Python has a keyword that means "don't do anything":
if primary_condition:
pass
elif secondary_condition1:
do_one_thing()
elif secondary_condition2:
do_another_thing()
You could say that { } is functionally equivalent to pass, which it is. But it's not (to humans) semantically equivalent. pass means "do nothing," while to me, { } typically means "there used to be code here and now there isn't."
But in general, if I get to the point where it's even an issue whether sticking a ! in front of a condition makes it harder to read, I've got a problem. If I find myself writing code like this:
while (keypress != escape_key && keypress != alt_f4_key && keypress != ctrl_w_key)
it's pretty clear to me that what I'm actually going to want over the long term is more like this:
var activeKeys = new[] { escape_key, alt_f4_key, ctrl_w_key };
while (!activeKeys.Contains(keypress))
because that makes explicit a concept ("these keys are active") that's only implicit in the preceding code, and makes the logic "this is what you happens when an inactive key is pressed" instead of "this is what happens when a key that's not one ESC, ALT+F4 or CTRL+W is pressed."

Categories

Resources