How can I make sure that a certain instance of a class will never be null? Someone told me to use Debug.Assert() but by doing so, I would only ensure that the code works in debug mode, whereas I want to ensure the is-never-null condition in release as well.
For example, in the past I wrote code like:
public string MyString
{
get
{
if(instance1.property1.Equals("bla"))
{
return bla;
}
}
}
But this throws an exception if instance1 is null. I would like to avoid making such mistakes and generating such exceptions in the future.
Thanks,
please see a specific example below that illustrates the problem:
I have a method that authenticates users based on responses from a server. The method is this:
/// <summary>
/// attempts authentication for current user
/// </summary>
/// <returns></returns>
public AuthResult CheckUser()
{
WebRequest request = WebRequest.Create(GetServerURI);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string postdata = "data=" + HttpUtility.UrlEncode(SerializeAuth());
byte[] arr = Utils.AppDefaultEncoding.GetBytes(postdata);
request.ContentLength = arr.Length;
request.Timeout = Convert.ToInt32(TimeUtils.GetMiliseconds(10, TimeUtils.TimeSelect.Seconds));
Stream strToWrite = request.GetRequestStream();
strToWrite.Write(arr, 0, arr.Length);
WebResponse response = request.GetResponse();
using (Stream dataFromResponse = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataFromResponse))
{
string readObj = reader.ReadToEnd();
return DeserializeAuth(readObj);
}
}
}
to call this method, i use
_authenticationResult = authObj.CheckUser();
I also have this property, among others
public ResultType AuthResult
{
get
{
if (_authenticationResult.auth == "1")
return ResultType.Success;
if (_authenticationResult.auth == "0")
return ResultType.FailAccountExpired;
if (_authenticationResult.auth == "-1")
return ResultType.FailWrongUsernameOrPassword;
if (_authenticationResult.auth == "-2")
return ResultType.Banned;
return ResultType.NoAuthDone;
}
}
public enum ResultType { Success, FailWrongUsernameOrPassword, FailAccountExpired, NoAuthDone, Banned }
what happened was that _authenticationResult was null once, and the property AuthResult threw a nullref at attempting "null.auth". How can I ensure (perhaps inside the CheckUser() method) that it never returns null.
When i debugged the app it never happened. But in production, when the server timed out sometimes the method returned null.
Thanks,
I think you need to understand how
instance1
, and subsequentlyproperty1
are going to be instantiated, and only instantiate them in such a way that they cannot be null. This is generally done by checking arguments at construction, e.g.:If you create your types in such a way that they cannot exist in an invalid state, you ensure that your dependent code won't fall over on
null
values.Otherwise, we'd need to see a fuller example of what you are doing to give you more concrete advice.
The other thing to consider, is what state your class can exist in which is a required state of operation, vs. an optional state of operation. That being, what members are required for your class to operate, and you should endeavour to design your classes such that they always have the required state, e.g.:
In my example type, I'm requiring that my
Forename
andSurname
value have a non-null value. This is enforced through my constructor... myPerson
type can never be instantiated with null values (although, perhaps empty values are just as bad, so checkingIsNullOrWhiteSpace
and throwing an appropriateArgumentException
is the route, but lets keep it simple).If I were to introduce an optional field, I would allow it to mutate the state of my
Person
instance, e.g., give it a setter:My
Person
type still enforces the required fields for operation, but introduces an optional field. I then need to take this into consideration when performing an operation which uses these members:(Although that is not the greatest example of a
ToString
).