How to check if DateTime object was not assigned? - c#

So, First of all. Code:
I've got a class:
public class Myobject
{
public string Code { get; set; }
public DateTime? StartDate { get; set; }
}
And this is part of very simple source:
MyObject mo = new MyObject();
mo.Code= "sth";
// NO action on StartDate property!
if (mo.StartDate.HasValue)
{
sc.Parameters.Add(new SqlParameter("#inStartDate", mo.StartDate.Value));
}
else
{
sc.Parameters.Add(new SqlParameter("#inStartDate", DBNull.Value));
}
Simple 'if' - Sql Server 2008, throw an error - when gets null Datetime (it has to be DBNull.Value)
So I want to check it first, and then pass right value or DBNull.
My problem is - this 'if' always retruns true! Why!?
Also tried that:
if (mo.StartDate.Value == null)
but it always returns false. How come it is not a null? It was not even created..
So.. How to check if DateTime object was not assigned?

Try this:
if (mo.StartDate.GetValueOrDefault() != DateTime.MinValue)
{
// True - mo.StartDate has value
}
else
{
// False - mo.StartDate doesn't have value
}

should just be able to do
mo.StartDate != null
instead of
mo.StartDate.Value != null

Running the simplest test with that class (as you presented it) yields false:
var mo = new Myobject();
Console.WriteLine(mo.StartDate.HasValue);
Output is False.
I'd put a breakpoint on your constructor (if you have one), make sure nothing else is getting assigned, and walk through any methods called along the way to make sure there's nothing else setting the property that may not be immediately obvious...
Can you post more code, perhaps? There must be something in code not posted setting the property.

.HasValue and ==null are the ways to check whether DateTime? is assigned a value or not. You are doing it right. There might be problem somewhere else that .HasValue returns true always.

The way you're checking for null is fine, there must be something else that's setting the field's value.
To find what's setting the field you could right-click it then do find all references, then scan the list for any assignments.
Failing that, you could change it to an explicitly defined property temporarily and set a breakpoint within the set method, then execution will pause whenever the value is set and you can look up the call stack.

Related

Filtering my property in a getter

Here is my code:
private Analyst _PrimaryAnalyst;
public Analyst PrimaryAnalyst
{
get
{
Analyst activeAnalysts;
if (this.PrimaryAnalyst.IsActive == true)
{
activeAnalysts = _PrimaryAnalyst;
}
return activeAnalysts; //"Use of unassigned local variable"
}
set
{
SetPropertyValue("PrimaryAnalyst", ref _PrimaryAnalyst, value);
}
}
Basically I am trying to filter my Analyst property based on if they are marked Active or not. Then I want to to return only Active Analysts. (Based on a bool property of Analyst), I am getting an error on the return statement saying "Use of unassigned local variable"
However I am clearly assigning it in the if statement?
In C# you can not use a local variable before assigning it a value.
C# Language Specification, section 1.6.6.2
C# requires a local variable to be definitely assigned before its
value can be obtained
lets get to your code
what happen if this.PrimaryAnalyst.IsActive is false? Yes, Use of unassigned local variable
you can fix this by initializing the local variable.
Analyst activeAnalysts = null;
or
if (this.PrimaryAnalyst.IsActive == true)
{
activeAnalysts = _PrimaryAnalyst;
}
else
{
activeAnalysts = null;
}
but there is another problem here. Your code leads to StackOverflowException because you are calling a method inside itself (recursion) but there is no way out of it so it leads to StackOverflowException
you should change the line this.PrimaryAnalyst.IsActive == true to _PrimaryAnalyst.IsActive == true
Change the first line of the getter to:
Analyst activeAnalysts = null;
The issue is that if the if statement evaluates to false, then the value is never set, so the compiler doesn't know what it should return.
The reason you're getting the error is that not all code paths lead to an assignment. You should either initialize the variable before the if, or include an else and assign it to something there.
Also, you should be checking your private variable in the if statement instead of the public one (to avoid a StackOverflowException), and, assuming that Analyst is a nullable class, you should also ensure it's not null before checking IsActive. A property getter should not throw an exception.
Your getter can be also be simplified using a ternary assignment:
get
{
return (_PrimaryAnalyst != null && _PrimaryAnalyst.IsActive)
? _PrimaryAnalyst
: null;
}

Scope of string inside lambda

I have an interesting scenario in which I've built a validation checking system that maintains a series of requirements in the form List<Tuple<Func<bool>, string>> where the Func should return true if validation failed and false otherwise. The string is a corresponding rejection description that describes the condition should the test fail.
In more simple tests like the following the validation system is quite simple:
validationChecks.Add(Tuple.Create<Func<bool>, string>(() =>
value1 == requiredValue, "value 1 did not have the required value"));
I'm struggling to understand the scope of variables within the lambda for the Func in a more advanced scenario in which the rejection string is calculated in a call to another part of the system. The scenario looks something like this:
string rejectionString = null;
validationChecks.Add(Tuple.Create<Func<bool>, string>(() => {
rejectionString = CallToAnotherMethodThatReturnsString(parameter);
if (rejectionString != null) {
return true;
} else {
return false;
}
}, rejectionString));
EDIT: As observed through testing, when this check fails the rejectionString from the Tuple is still null. I want the rejectionString that was generated by the CallToAnotherMethod to be used instead, is there any way I can do this using ref or otherwise? I need the Func's code to be able to affect the value of the string inside Item2 of the Tuple.
The problem is that the code inside of CallToAnotherMethodThatReturnsString might be code that I only want executed ONCE. However should the check fail I want to use the string that would have been returned from it as my rejection description in the Tuple. I'm unable to tell at this point what the effect of my use of rejectionString in this second example will accomplish? Will rejectionString inside the Tuple always be null? Or if CallToAnotherMethodThatReturnsString returns a different value will it be updated?
Just an idea that might work. I think if you change your second Tuple parameter to a Func that returns string instead of string value, you could come close to what you need.
string rejectionString = null;
validationChecks.Add(Tuple.Create<Func<bool>, Func<string>>(() =>
{
rejectionString = CallToAnotherMethodThatReturnsString(parameter);
if (rejectionString != null) {
return true;
} else {return false;}
},
()=>rejectionString));
In the first case your validation check would be set as
validationChecks.Add(Tuple.Create<Func<bool>, Func<string>>(() => value1 == requiredValue, ()=>"value 1 did not have the required value"));
And your validation is logic is then
if(validationChecks[0].Item1()==false)
var error = validationChecks[0].Item2();

initializing an object with strings to null

I have an object model somewhat like this:
public class MyObject
{
public string String1 { get; set; }
public string String2 { get; set; }
...
}
When the object initializes, all the string values are set to null.
Later on, I'm writing a method that evaluates the value of these strings to prepare an update in the DB. Something like this:
if (TheObject.String1 != null) { TheObjectInDB.String1 = TheObject.String1; }
if (TheObject.String2 != null) { TheObjectInDB.String2 = TheObject.String1; }
TheObject is an instance of MyObject and TheObjectInDB is an instance of the linq-to-sql map for the table I'm updating.
My question is this: is using the null a safe way to do it or could it cause problems later? Should I create a constructor that initializes these strings to "" and in the update check if the strings are = "" instead of = null?
Thanks for the advice.
There is nothing more, or less safe about null or an empty string. It is entirely your choice. Because both are often used to indicate the abscence of data or information, there is a convenience method string.IsNullOrEmpty that allows you to accept either value.
In your case, I would stick with the easiest option, null.
You could initialize both properties to string.Empty (preferred to "") and then check for string.Empty when setting the properties, however only if you can guarantee that either:-
a) the value being set is never string.Empty
or
b) the value being set is string.Empty but the values are only set once
I'd stick with checking for null to avoid either of the above causing potential issues in the future.
There is no problem here, the code you are using should work without any problems.
I can't even think of 'problems that this can cause 'later''.

Is this redundant code?

I'm upgrading a system and am going through another developers code (ASP.NET in C#).
I came across this:
private ReferralSearchFilterResults ReferralsMatched
{
get
{
if (Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] == null || Session[SESSION_REFERRAL_SEARCHFILTERRESULTS].GetType() != typeof(ReferralSearchFilterResults))
return null;
else
return (ReferralSearchFilterResults)Session[SESSION_REFERRAL_SEARCHFILTERRESULTS];
}
set
{
if (value == null)
{
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
else if (value.GetType() == typeof(ReferralSearchFilterResults))
{
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
}
}
Is checking the type on the setter unnecessary? Surely, if I set the property to something other than a ReferralSearchFilterResults object, the code wouldn't even compile? Am I missing something or am I right to think this can be achieved just by using:
set
{
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
The original code prevents any subclasses of ReferralSearchFilterResults from being set or get to or from the property. This is because value.GetType() will return the actual Type of the object referenced by value. If that Type is a subclass of ReferralSearchFilterResults, then it will not equals typeof(ReferralSearchFilterResults).
I'm not sure of your context here, so I can't tell you whether that's correct behaviour or not. If it's intended behaviour, it does smell a bit dirty as it will silently ignore any assignments of subclasses. But I can't really judge without more context.
I think you're right - the setter shouldn't compile if provided with something of that cannot be implicitly cast to a ReferralSearchFilterResults.
For the get part, you can use
return Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] as ReferralSearchFilterResults;
This returns the value if it can be casted to ReferralSearchFilterResults, otherwise null.
Jamie you are correct. The Type check on the Setter is unnecessary in this case because value must be a ReferralSearchFilterResults.
One other change you might consider is using the is and as keywords in place of comparing Type objects.
private ReferralSearchFilterResults ReferralsMatched
{
get
{
if (Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] == null || !(Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] is ReferralSearchFilterResults))
return null;
else
return Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] as ReferralSearchFilterResults;
}
set
{
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
}
Session variables are of type object, so you can store anything inside those. But in this case the setter itself prevents the programmer from assigned an other object type than ReferralSearchFilterResults and derived objects.
So the check, as you pointed out, itself is unneccessary. Additionally it does not let a programmer assign a object that derives from ReferralSearchFilterResults.
But I would use Session.Remove rather than just setting the variable to null, because the session variable would still exists in the http context if only set to null.
So:
set
{
if (value == null)
Session.Remove(SESSION_REFERRAL_SEARCHFILTERRESULTS);
else
Session[SESSION_REFERRAL_SEARCHFILTERRESULTS] = value;
}
I can understand the type check in the get bit, but as you say, in the setter, you can't pass in anything that's not a ReferralSearchFilterResults, as the code would fail at the time of compilation.
(Could be some old habit, the other developer had)

Good practices for initialising properties?

I have a class property that is a list of strings, List.
Sometimes this property is null or if it has been set but the list is empty then count is 0.
However elsewhere in my code I need to check whether this property is set, so currently my code check whether it's null and count is 0 which seems messy.
if(objectA.folders is null)
{
if(objectA.folders.count == 0)
{
// do something
}
}
Any recommendation on how this should be handled?
Maybe I should always initialise the property so that it's never null?
When I have List as a property, I usually have something that looks like the following (this is not a thread safe piece of code):
public class SomeObject
{
private List<string> _myList = null;
public List<string> MyList
{
get
{
if(_myList == null)
_myList = new List<string>();
return _myList;
}
}
}
Your code would then never have to check for null because the Property would be initialized if used. You would then only have to check for the Count.
Right now your code will Always throw a Null Pointer exception, you are checking for Null and if it IS null - you're trying to access an object which does not exist.
If for your application the collection being a null reference never has a different meaning than the collection being empty, then yes, I would say you should always initialize it and this way remove the null checks from the remaining code.
This approach only makes sense if the property setter does not allow to change it to a null reference after initialization.
You have three options (and you need to decide based on your project):
Create a method to check for NullOrNoElements. Pro: Allows both null and no entries. Con: You have to call it everywhere you want to use the property.
Preinitialize with a list. Pro: Thread-save and very easy. Con: will use memory even when not used (depending on how many instances you have this may be a problem)
Lazy initialize Pro: Does only use memory when really used. Con: NOT thread save.
private List<string> lp = null;
public List<string> ListProp
{
get
{
if(lp == null)
lp = new List<string>();
return lp;
}
}
You could always initialize the property so it's an empty List. Then you can just check the count property.
List<String> Folder = Enumerable.Empty<String>();
I once wrote an extension method for ICollection objects that checked if they were null or empty
public static Boolean IsNullOrEmpty<T>(this ICollection<T> collection)
{
return collection == null ? true : collection.Count() == 0;
}
public static Boolean IsPopulated<T>(this ICollection<T> collection)
{
return collection != null ? collection.Count() > 0 : false;
}
You could do this in a single IF
if(objectA.folders is null || objectA.folders.count == 0)
Or you could create a boolean property in the class which checks this status for you and returns a result
public bool objectA.FolderIsNullOrEmpty
{
get { return objectA.folders is null || objectA.folders.count == 0;}
}
If it does not make a difference to your application, I would rather recomend initializing the List to start with.
You could handle this by initializing the object in the constructor. This is usually where this type of thing is done. Although I see nothing wrong with your current code. No point in initializing stuff that doesn't exist yet, it just wastes memory.
Its a good question. I would add a method to objectA FoldersNullOrEmpty() that you can use eg
public virtual FoldersNullOrEmpty()
{
return (folders == null || folders.count == 0)
}
I almost always initialize lists and even make sure they can't be set to null if exposed by any setters. This makes using them much easier.

Categories

Resources