Create Null Object

  • Thread starter Thread starter tshad
  • Start date Start date
T

tshad

How do you create a null object if the Constructor finds an error and thus
would make the object invalid?

If I have a Class Role and during the constructer there is something wrong,
I want to do something like the following:

public Role()
{
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
Don't create the object and pass back a null
}
 
tshad said:
How do you create a null object if the Constructor finds an error and thus
would make the object invalid?

There's no such things as a null object.
If I have a Class Role and during the constructer there is something wrong,
I want to do something like the following:

public Role()
{
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
Don't create the object and pass back a null
}

It sounds like you need a factory method:

public static Role CreateRole()
{
string connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString=="")
{
return null;
}
return new Role(connectionString);
}
 
Jon Skeet said:
tshad said:
How do you create a null object if the Constructor finds an error and
thus
would make the object invalid?

There's no such things as a null object.
If I have a Class Role and during the constructer there is something
wrong,
I want to do something like the following:

public Role()
{
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
Don't create the object and pass back a null
}

It sounds like you need a factory method:

Could be.

I have never used this, so I don't know.

But from your example, it looks like what I need. I will need to look at
how it works to see.

What I want to use it for is to create a role or user object based on a
RoleID or UserID. If the roleID or userID doesn't exist, then I want to
send back a null and not create the object (for what would be the point).

Thanks,

Tom
public static Role CreateRole()
{
string connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString=="")
{
return null;
}
return new Role(connectionString);
}
 
As a reminder, as an addition to that, so that users of the class don't just
call the constructor and circumvent your CreateRole() static method, make
the constructo private, as in:

private Role() {}


Scott

tshad said:
Jon Skeet said:
tshad said:
How do you create a null object if the Constructor finds an error and
thus
would make the object invalid?

There's no such things as a null object.
If I have a Class Role and during the constructer there is something
wrong,
I want to do something like the following:

public Role()
{
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
Don't create the object and pass back a null
}

It sounds like you need a factory method:

Could be.

I have never used this, so I don't know.

But from your example, it looks like what I need. I will need to look at
how it works to see.

What I want to use it for is to create a role or user object based on a
RoleID or UserID. If the roleID or userID doesn't exist, then I want to
send back a null and not create the object (for what would be the point).

Thanks,

Tom
public static Role CreateRole()
{
string connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString=="")
{
return null;
}
return new Role(connectionString);
}
 
Scott said:
As a reminder, as an addition to that, so that users of the class don't just
call the constructor and circumvent your CreateRole() static method, make
the constructo private, as in:

private Role() {}

Note that you don't need to supply an extra private parameterless
constructor if you have other constructors (which would probably also
be private). The compiler only supplies a public parameterless
constructor if no constructors are specified in the code.
 
tshad said:
How do you create a null object if the Constructor finds an error and thus
would make the object invalid?

If I have a Class Role and during the constructer there is something
wrong, I want to do something like the following:

public Role()
{
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
Don't create the object and pass back a null
}

In addition to the other suggestions - this looks like a situation to me,
where you actually detect an invalid state during object construction. In
that case, I would probably throw an exception in the constructor.

I see the distinguishing factors like this: if the condition is part of
your normal application flow logic, you'll want to detect and handle it
without exceptions - but you need to do that "from the outside", meaning
not from the constructor. A factory method may be fine for that. But if
the condition is something that shouldn't occur unless something went
wrong, I'd rather throw an exception from the constructor - no need to
introduce additional management code in the form of factory methods or
other "outside" checks for this error situation.


Oliver Sturm
 
Oliver Sturm said:
tshad said:
How do you create a null object if the Constructor finds an error and thus
would make the object invalid?

If I have a Class Role and during the constructer there is something
wrong, I want to do something like the following:

public Role()
{
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
Don't create the object and pass back a null
}

In addition to the other suggestions - this looks like a situation to me,
where you actually detect an invalid state during object construction. In
that case, I would probably throw an exception in the constructor.

How do you do that?

If you are already in the constructor, what tells it to send back the null
and not to create the object in the first place (or at least destroy what it
has already created).

Thanks,

Tom
 
Ah, yes, I forgot about that, Jon.

Scott


Jon Skeet said:
Note that you don't need to supply an extra private parameterless
constructor if you have other constructors (which would probably also
be private). The compiler only supplies a public parameterless
constructor if no constructors are specified in the code.
 
tshad said:
If I have a Class Role and during the constructer there is something
wrong, I want to do something like the following:

public Role()
{
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
Don't create the object and pass back a null
}

In addition to the other suggestions - this looks like a situation to me,
where you actually detect an invalid state during object construction. In
that case, I would probably throw an exception in the constructor.

How do you do that?

If you are already in the constructor, what tells it to send back the null
and not to create the object in the first place (or at least destroy what
it has already created).

I didn't say I'd "send back null", but I'd throw an exception in this
case. Like this:

public Role() {
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
throw new InvalidOperationException("Role can't be created without a valid connection string.");
}


Oliver Sturm
 
Oliver Sturm said:
tshad said:
If I have a Class Role and during the constructer there is something
wrong, I want to do something like the following:

public Role()
{
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
Don't create the object and pass back a null
}

In addition to the other suggestions - this looks like a situation to me,
where you actually detect an invalid state during object construction. In
that case, I would probably throw an exception in the constructor.

How do you do that?

If you are already in the constructor, what tells it to send back the null
and not to create the object in the first place (or at least destroy what
it has already created).

I didn't say I'd "send back null", but I'd throw an exception in this
case. Like this:

public Role() {
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
throw new InvalidOperationException("Role can't be created without
a valid connection string.");
}
But what does the code that called it get back?

Role newRole = new Role();

Tom
 
tshad said:
In addition to the other suggestions - this looks like a situation to me,
where you actually detect an invalid state during object construction. In
that case, I would probably throw an exception in the constructor.

How do you do that?

If you are already in the constructor, what tells it to send back the null
and not to create the object in the first place (or at least destroy what
it has already created).

I didn't say I'd "send back null", but I'd throw an exception in this
case. Like this:

public Role() {
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
throw new InvalidOperationException("Role can't be created without a valid connection string.");
}
But what does the code that called it get back?

Role newRole = new Role();

I did explain that in my original post, didn't I? Here's what I said:

I see the distinguishing factors like this: if the condition is part of
your normal application flow logic, you'll want to detect and handle it
without exceptions - but you need to do that "from the outside", meaning
not from the constructor. A factory method may be fine for that. But if
the condition is something that shouldn't occur unless something went
wrong, I'd rather throw an exception from the constructor - no need to
introduce additional management code in the form of factory methods or
other "outside" checks for this error situation.

So, to elaborate: the code that calls the constructor by using the new
keyword doesn't get anything back in this case, because an exception has
been thrown. Apparently you don't know what throwing exceptions is about -
it might help you to read up on this at this (MSDN) link:
http://shrinkster.com/8ds

Throwing an exception in a situation like this is the right thing to do,
as I see it, because neither the constructor code itself nor the code
calling into that code are likely to be able to do anything about the
problem, nor are they responsible for the problem in the first place. IOW,
the problem is not part of the normal application logic and there's no
step-by-step plan of what to do in this case.

Obviously, I'm basing this on assumptions about the sample code you were
showing, but the fact that no connection string can be read from the
application settings sounds pretty much like a global error to me. So I
throw an exception because at this point I simply don't care who, if
anybody, is going to catch it. The exception, so to speak, is the tool
that I use to make sure this error condition can not be ignored under any
normal circumstances - if no part of my code ever catches it, it'll
surface in the debugger or a framework error message to the end user.


Oliver Sturm
 
Oliver Sturm said:
tshad said:
In addition to the other suggestions - this looks like a situation to
me, where you actually detect an invalid state during object
construction. In that case, I would probably throw an exception in the
constructor.

How do you do that?

If you are already in the constructor, what tells it to send back the
null and not to create the object in the first place (or at least
destroy what it has already created).

I didn't say I'd "send back null", but I'd throw an exception in this
case. Like this:

public Role() {
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
throw new InvalidOperationException("Role can't be created without
a valid connection string.");
}
But what does the code that called it get back?

Role newRole = new Role();

I did explain that in my original post, didn't I? Here's what I said:

I see the distinguishing factors like this: if the condition is part of
your normal application flow logic, you'll want to detect and handle it
without exceptions - but you need to do that "from the outside", meaning
not from the constructor. A factory method may be fine for that. But if
the condition is something that shouldn't occur unless something went
wrong, I'd rather throw an exception from the constructor - no need to
introduce additional management code in the form of factory methods or
other "outside" checks for this error situation.

So, to elaborate: the code that calls the constructor by using the new
keyword doesn't get anything back in this case, because an exception has
been thrown. Apparently you don't know what throwing exceptions is about -
it might help you to read up on this at this (MSDN) link:
http://shrinkster.com/8ds

Throwing an exception in a situation like this is the right thing to do,
as I see it, because neither the constructor code itself nor the code
calling into that code are likely to be able to do anything about the
problem, nor are they responsible for the problem in the first place. IOW,
the problem is not part of the normal application logic and there's no
step-by-step plan of what to do in this case.

Obviously, I'm basing this on assumptions about the sample code you were
showing, but the fact that no connection string can be read from the
application settings sounds pretty much like a global error to me. So I
throw an exception because at this point I simply don't care who, if
anybody, is going to catch it. The exception, so to speak, is the tool
that I use to make sure this error condition can not be ignored under any
normal circumstances - if no part of my code ever catches it, it'll
surface in the debugger or a framework error message to the end user.

You're right. It was sample code. I might be looking into a database for
something that is not there and if not I may not want to create the object.

As far as the null goes (and I know this is VB.Net - but would be the same
as C#), I check if an object is created in lots of places. One for
instance:

objCmd.ExecuteNonQuery()
if not(objCmd is Nothing)
If objConn.State = System.Data.Connectionstate.open then
objConn.Close()
end if
end if

If I am looking at something in a grid (label for instance) and it isn't
there, the object would be null.

That was what I was trying to do. Not create the object - for some reason -
and be able to check if the object was null.

Thanks,

Tom
 
tshad said:
Oliver Sturm said:
tshad said:
In addition to the other suggestions - this looks like a situation to
me, where you actually detect an invalid state during object
construction. In that case, I would probably throw an exception in the
constructor.

How do you do that?

If you are already in the constructor, what tells it to send back the
null and not to create the object in the first place (or at least
destroy what it has already created).

I didn't say I'd "send back null", but I'd throw an exception in this
case. Like this:

public Role() {
connectionString = ConfigurationSettings.AppSettings["x"];
if (connectionString == "")
throw new InvalidOperationException("Role can't be created
without a valid connection string.");
}

But what does the code that called it get back?

Role newRole = new Role();

I did explain that in my original post, didn't I? Here's what I said:

I see the distinguishing factors like this: if the condition is part of
your normal application flow logic, you'll want to detect and handle it
without exceptions - but you need to do that "from the outside", meaning
not from the constructor. A factory method may be fine for that. But if
the condition is something that shouldn't occur unless something went
wrong, I'd rather throw an exception from the constructor - no need to
introduce additional management code in the form of factory methods or
other "outside" checks for this error situation.

So, to elaborate: the code that calls the constructor by using the new
keyword doesn't get anything back in this case, because an exception has
been thrown. Apparently you don't know what throwing exceptions is
about - it might help you to read up on this at this (MSDN) link:
http://shrinkster.com/8ds

Throwing an exception in a situation like this is the right thing to do,
as I see it, because neither the constructor code itself nor the code
calling into that code are likely to be able to do anything about the
problem, nor are they responsible for the problem in the first place.
IOW, the problem is not part of the normal application logic and there's
no step-by-step plan of what to do in this case.

Obviously, I'm basing this on assumptions about the sample code you were
showing, but the fact that no connection string can be read from the
application settings sounds pretty much like a global error to me. So I
throw an exception because at this point I simply don't care who, if
anybody, is going to catch it. The exception, so to speak, is the tool
that I use to make sure this error condition can not be ignored under any
normal circumstances - if no part of my code ever catches it, it'll
surface in the debugger or a framework error message to the end user.

You're right. It was sample code. I might be looking into a database for
something that is not there and if not I may not want to create the
object.

As far as the null goes (and I know this is VB.Net - but would be the same
as C#), I check if an object is created in lots of places. One for
instance:

objCmd.ExecuteNonQuery()
if not(objCmd is Nothing)
If objConn.State = System.Data.Connectionstate.open then
objConn.Close()
end if
end if

If I am looking at something in a grid (label for instance) and it isn't
there, the object would be null.

That was what I was trying to do. Not create the object - for some
reason - and be able to check if the object was null.

Also, what I decided to do to solve my problem was just add a private
variable (status) that I can look at to see if the object is valid.

What I am doing is creating a role and one of the constructors is passing a
role ID which would go to the database to get the description.

But if the Role had been delete, it would not be there. In that case I
wanted to pass back null (be able to test if object was null). If this is a
problem, I can just test to see if status is 0 or 1 (number of rows that the
Sql Statement got back).

private int status;

public Role(int roleID)
{
DataSet dataSet = new DataSet();
DbObject myDbObject = new DbObject();
SqlParameter[] parameters = {
new SqlParameter("@RoleID",SqlDbType.Int,20) };

parameters[0].Value = roleID;

dataSet = myDbObject.RunProcedure("GetRoleDetails",parameters,"Roles");
// executes the Stored Procedure to get the role description.

status = dataSet.Tables[0].Rows.Count;

if (status == 0) return;

DataRow role = dataSet.Tables["Roles"].Rows[0];
this.roleID = (int)role["RoleID"];
this.description = (string)role["Description"];

dataSet.Dispose();
}

In my routine, I would do the following

Role theRole = new Role(14);
if (theRole = 0) do something not a valid object. There is no
such Role.

Thanks,

Tom
 
Back
Top