This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 2 years ago.
So i know this is a common problem but the solutions ive seen are not working for me, Sorry if i havent given enough information. Line 31 is where the error happens according to unity. Here is the code
using UnityEngine;
using UnityEngine.UI;
public class Scoring : MonoBehaviour
public Text Score1;
private int scorePoint1;
// Update is called once per frame
void Start()
{
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.name == ("WallLeft"))
{
scorePoint1 += 1;
Debug.Log("ScorePoint");
}
}
void Update()
{
Score1 = GetComponent<Text>();
Score1.text = "" + scorePoint1.ToString();
}
}
I have tried multiple answers and it seems like everything is connected UI wise (I have tested it with different stuff and it worked) its just this is not working. Im almost it is the scorePoint1 variable that is causing it as i have done it with other variables and it worked but as soon as i switched it out for that it no longer worked. Thanks for the help!
Quick edit: i did a null check as told to on the lines and i confirmed Score1.text = "" + scorePoint1.ToString() ?? string.Empty; this line is what is causing it. Still unsure how to fix it but atleast i know this for certain
From your code any of these expressions can be the cause of the problem:
if (col.gameObject.name == ("WallLeft"))
Score1.text = "" + scorePoint1.ToString();
Debug your code and you will find there's a null check needed in one of those 3 places.
Also as a separate note:
"" + scorePoint1.ToString();
This will potentially allocate 3 strings in memory. First an empty string and then the scorePoint1 as string and then third string where the 2 values are concatenated together.
This is very bad for performance especially in a game or in a loop. If you want a string that is never null, do this instead. That will be 3 times more memory efficient:
scorePoint1?.ToString() ?? string.Empty;
Ad1:
Score1.text = "" + scorePoint1.ToString() ?? string.Empty;
The ?? is null coalescing.
= If left side is null, use right side instead.
But that is not your problem, you can't call ToString() on a null object.
In my example I use the ?. null-conditional.
= If left side is null, don't call the method/property after ?. and return null.
This is what you want, it will never fail even if there's null.
Score1.text = scorePoint1?.ToString() ?? string.Empty;
So you can see if scorePoint1 is null, ToString() is never called and prevents your error. The expression scorePoint1?.ToString() returns null, which is handled by the null coalesce and gets replaced by string.Empty.
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.
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.
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."
I am having trouble implementing a sort algo (merge) for singly list as defined below
My mergesort method always gives me null..I am not able to figure out what is wrong
Can you guys help me out?
Node class
public class Node
{
private int data;
private Node next;
}
Linked List class
public class SSL
{
private Node head;
}
My merge sort code
public static void MergeSort(SSL a)
{
SSL x = new SSL();
SSL y = new SSL();
if (a.Head == null || a.Head.Next == null) // base case if list has 0 or 1 element
return;
AlternateSplitting(a, x, y);
MergeSort(x);
MergeSort(y);
a = SortedMerge(x, y);
}
I implemented following helper methods to implement merge sort
AlternateSplitting: This method will split the list into 2 lists
public static void AlternateSplitting(SSL src, SSL odd, SSL even)
{
while (src.Head != null)
{
MoveNode(odd, src);
if (src.Head != null)
MoveNode(even, src);
}
} // end of AlternateSplitting
This method will merge the 2 list and return a new list
public static SSL SortedMerge(SSL a, SSL b)
{
SSL c = new SSL();
if (a.Head == null)
return b;
else
if (b.Head == null)
return a;
else
{
bool flagA = false;
bool flagB = false;
Node currentA = new Node();
Node currentB = new Node();
while (!flagA && !flagB)
{
currentA = a.Head;
currentB = b.Head;
if (currentA.Data < currentB.Data)
{
MoveNodeToEnd(a, c);
currentA = a.Head;
if (currentA== null)
flagA = true;
}
else
if (currentA.Data > currentB.Data)
{
MoveNodeToEnd(b, c);
currentB = b.Head;
if (currentB== null)
flagB = true;
}
} // end of while
if (flagA)
{
while (currentB != null)
{
MoveNodeToEnd(b, c);
currentB = b.Head;
}
}
else
if(flagB)
{
while (currentA != null)
{
MoveNodeToEnd(a, c);
currentA = a.Head;
}
}
return c;
} // end of outer else
} // end of function sorted merge
I am not able to figure out what is
wrong Can you guys help me out?
Find a bug and you fix it for a day. Teach how to find bugs and believe me, it takes a lifetime to fix the bugs. :-)
Your fundamental problem is not that the algorithm is wrong -- though, since it gives incorect results, it certainly is wrong. But that's not the fundamental problem. The fundamental problem is that you don't know how to figure out where a program goes wrong. Fix that problem first! Learn how to debug programs.
Being able to spot the defect in a program is an acquired skill like any other -- you've got to learn the basics and then practice for hundreds of hours. So learn the basics.
Start by becoming familiar with the basic functions of your debugger. Make sure that you can step through programs, set breakpoints, examine local variables, and so on.
Then write yourself some debugging tools. They can be slow -- you're only going to use them when debugging. You don't want your debugging tools in the production version of your code.
The first debugging tool I would write is a method that takes a particular Node and produces a comma-separated list of the integers that are in the list starting from that node. So you'd say DumpNode(currentB) and what would come back is, say "{10,20,50,30}". Obviously doing the same for SSL is trivial if you can do it for nodes.
I would also write tools that do things like count nodes in a list, tell you whether a given list is already sorted, and so on.
Now you have something you can type into the watch window to more easily observe the changes to your data structures as they flow by. (There are ways to make the debugger do this rendering automatically, but we're discussing the basics here, so let's keep it simple.)
That will help you understand the flow of data through the program more easily. And that might be enough to find the problem. But maybe not. The best bugs are the ones that identify themselves to you, by waving a big red flag that says "there's a bug over here". The tool that turns hard-to-find bugs into self-identifying bugs is the debug assertion.
When you're writing your algorithm, think "what must be true?" at various points. For example, before AlternateSplitting runs, suppose the list has 10 items. When it is done running, the two resulting lists had better have 5 items each. If they don't, if they have 10 items each or 0 items each or one has 3 and the other has 7, clearly you have a bug somewhere in there. So start writing debug-only code:
public static void AlternateSplitting(SSL src, SSL odd, SSL even)
{
#if DEBUG
int srcCount = CountList(src);
#endif
while (src.Head != null) { blah blah blah }
#if DEBUG
int oddCount = CountList(odd);
int evenCount = CountList(even);
Debug.Assert(CountList(src) == 0);
Debug.Assert(oddCount + evenCount == srcCount);
Debug.Assert(oddCount == evenCount || oddCount == evenCount + 1);
#endif
}
Now AlternateSplitting will do work for you in the debug build to detect bugs in itself. If your bug is because the split is not working out correctly, you'll know immediately when you run it.
Do the same thing to the list merging algorithm -- figure out every point where "I know that X must be true at this point", and then write a Debug.Assert(X) at that point. Then run your test cases. If you have a bug, then the program will tell you and the debugger will take you right to it.
Good luck!