Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I don't know before this asked or not, but I am confuse in below of code block.
CODE 1
if (String.IsNullOrEmpty(control.Text.Trim()))
{
// Code to execute
}
CODE 2
if (control.Text.Trim() == "")
{
// Code to execute
}
CODE 3
if (control.Text.Trim() == null)
{
// Code to execute
}
CODE 4
if (control.Text.Trim() == string.Empty)
{
// Code to execute
}
According to me all are working to me.
I just feeling wonder that what is the different in between in this 4 code block.
Let's start from primitives:
The first block checks if the string control.Text.Trim() is null or String.Empty.
The second block checks if the string control.Text.Trim() is "".
The third block checks if the string control.Text.Trim() is null.
The fourth block checks if the string control.Text.Trim() is String.Empty; this is exactly the same as the second block: "" equals String.Empty.
Fine, that's easy to understand. However, note that String.Trim() will never return null. Thus, the first block is equivalent to control.Text.Trim() == String.Empty. This is same as the second block and the fourth block, again because "" equals String.Empty. The third block will never be hit, ever.
Thus, the first, second and fourth blocks are equivalent to checking if control.Trim the empty string and the third block is useless and impossible to satisfy. Be careful, if control is null or control.Text is null you will hit an exception. Thus, you should strongly consider using `String.IsNullOrWhiteSpace and replacing everything with:
if(control != null && String.IsNullOrWhiteSpace(control.Text)) {
// code to execute
}
(unless you have some sort of guarantee that control is not null, in which case leave off the first part of the if).
More proper would be:
if (String.IsNullOrWhiteSpace(control.Text))
{
// Code to execute
}
that way you avoid null reference exception.
All your examples have the same bug, they will throw exception if variable is null.
You should also see diference between string.empty ("") and null, those are not the same things. Code 4 and code 2 are the same but both would throw if Text is null.
control.Text.Trim() is never going to be null
control might be
control.Text might be
in which case all three versions will blow chunks...
private static bool validControl(Control argControl)
{
return (argControl != null) && (argControl.Text != null) && (argControl.Text.Trim() != ""));
}
if (validControl(control))
{
// code to execute
}
maybe
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last month.
Improve this question
When I use StreamReader` for some reason the file I use isn't read. can I get any help?
I tried deleting the file and putting it in again but it didn't work
line is initialized to "", so the while loop is never entered. The condition should be line != null, not line == null like you currently have.
Your while loop condition is not correct it should be while(line != null), first of all line is initialized to empty string ("") so with current code the loop is never entered, secondary line = b.ReadLine(); should not be null until the file ends - from the StreamReader.ReadLine docs:
Returns String
The next line from the input stream, or null if the end of the input stream is reached.
Also this makes inner check if(line != null) obsolete.
Your while is not correct; just have a look:
...
string line = "";
// line is NOT null (it's empty) that's why
// while will not enter at all
while (line == null)
{
...
}
Let's change while into for, let pesky line (which is declared out of loop, is check in while, in if etc.) be a loop variable:
// Wrap IDisposable into using; do not Close them expplicitly
using (StreamReader b = new StreamReader("students.txt"))
{
...
for (string line = b.ReadLine(); line != null; line = b.ReadLine())
{
if (line == "2") { num2++; }
...
}
...
}
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.
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.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 4 years ago.
enter image description here
code:
CogFindCircleLastRunRecordConstants.BestFitCircle;
CogFindCircleTool_.Run();
if ((CogFindCircleTool_.Results.GetCircle() != null) && (CogFindCircleTool_.Results.GetCircle().Visible == true))
{
cogRecordDisplay1.Record = CogFindCircleTool_.CreateLastRunRecord().SubRecords["InputImage"];
This error is because .Results is null, yet you're trying to call the GetCircle() method on it.
One way to handle this is to use the null-conditional operator (?.), which returns null if the left hand side is null, otherwise continues with the method or property on the right hand side:
// If Results is null, the call to GetCircle will not happen, and the result will be null
// Not needed on the second condition, since '&&' would return 'false' right away
if ((CogFindCircleTool_.Results?.GetCircle() != null) &&
(CogFindCircleTool_.Results.GetCircle().Visible == true))
You could shorten your code even further by adding another .? when accessing the Visible property, and then we don't need to explicitly check for .GetCircle() != null first.
Below, if Results is null or GetCircle returns null, the expression will fail (because null != true), otherwise the condition Visible == true will be evaluated:
if (CogFindCircleTool_.Results?.GetCircle()?.Visible == true)
In the comments you stated that you have a line like this inside the if statement:
Label.SetXYText(CogFindCircleTool_.Results.GetCircle().CenterX,
CogFindCircleTool_.Results.GetCircle().CenterY, "(" +
Math.Round(CogFindCircleTool_.Results.GetCircle().CenterX, 3).ToString() +
"," + Math.Round(CogFindCircleTool_.Results.GetCircle().CenterY, 3).ToString() + ")");
One thing to improve performance is to capture the result fo the GetCircle() method once rather than calling it over and over again, which takes extra processing cycles. This will also make the code shorter and more readable. You can also use string interpolation instead of concatenation to shorten the code a little more.
You also mentioned that you were still getting a null reference exception on the inner line, which could only mean that Label is null (from what I can tell). If so, we could use the ?. operator when calling the SetXYText method:
// Capture the result of GetCircle() once
var circle = CogFindCircleTool_?.Results?.GetCircle();
if (circle?.Visible == true)
{
Label?.SetXYText(circle.CenterX, circle.CenterY,
$"({Math.Round(circle.CenterX, 3)},{Math.Round(circle.CenterY, 3)})");
}
Note that the code above will not do anything if something is null. If you want to do something else if circle is null or Label is null, then you should explicitly check that rather than use the ?. operator:
if (circle == null)
{
// do something if circle is null
}
else if (circle.Visible == true)
{
if (Label == null)
{
// do something if Label is null
}
else
{
Label.SetXYText(circle.CenterX, circle.CenterY,
$"({Math.Round(circle.CenterX, 3)},{Math.Round(circle.CenterY, 3)})");
}
}
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.