Three value data

  • Thread starter Thread starter Arto Viitanen
  • Start date Start date
A

Arto Viitanen

What is the best way to implement three value data, where the values are
no/yes/not applicable ?

I have used bool?, but I remember seeing some class (or most likely
enum) on .net for this.
 
What is the best way to implement three value data, where the values are
no/yes/not applicable ?

I have used bool?, but I remember seeing some class (or most likely
enum) on .net for this.

bool? is the most logical type to use for this, IMO. It's slightly
wasteful if you've got a huge array of them, but unless this is
actually a problem for you, I'd stick to it. It should be familiar to
any C# 2 programmer, whereas any alternative is unlikely to be.

Jon
 
bool? is the most logical type to use for this, IMO. It's slightly
wasteful if you've got a huge array of them, but unless this is
actually a problem for you, I'd stick to it. It should be familiar to
any C# 2 programmer, whereas any alternative is unlikely to be.

Jon

bool? is fine if you don't need to differentiate between 'not
applicable' and 'unanswered' and, as Jon says, will be familiar to any
developer.

If you needed four values (true, false, NA and Null) then I would
think that you could probably define a struct which contains a bool?,
and define a field of type Nullable<yourNullableBooleanStruct>

Then that field can be null (which I would take to mean has no value)
or not null, with an 'internal value' of true, false or null (if you
follow me)

I played a bit and came up with:

using System;
using System.Windows.Forms;
namespace nullabletest
{
public struct Troolean
{
private bool? boolValue;
public Troolean(bool? boolValue )
{
this.boolValue = boolValue;
}
public bool? BoolValue
{
get { return (boolValue); }
set {boolValue = value;}
}
}
public partial class Form1 : Form
{
private Troolean? likesCSharp;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
likesCSharp = null;
ShowResults();
likesCSharp = new Troolean(null);
ShowResults();
likesCSharp = new Troolean(true);
ShowResults();
likesCSharp = new Troolean(false);
ShowResults();
}
private void ShowResults()
{
if (likesCSharp == null)
{
checkBox1.Checked = false;
checkBox1.Enabled = false;
}
else
{
checkBox1.Enabled = true;
if (likesCSharp.Value.BoolValue == null)
{
checkBox1.CheckState = CheckState.Indeterminate;
}
else
{
if (likesCSharp.Value.BoolValue == true)
{
checkBox1.CheckState = CheckState.Checked;
}
else
{
checkBox1.CheckState = CheckState.Unchecked;
}
}
}
MessageBox.Show("Continue...");
}
}
}

OK it's not pretty, but I think it might be workable (or I might jsut
be tired and emotional and will regret it all in the morning!)

Incidentally, I noticed (this is the first time I have been playing
with nullable and structs) that I can't say

likesCSharp.Value.boolValue = true;

as the compiler tells me ...
Error 1 Cannot modify the return value of
'System.Nullable<nullabletest.Troolean>.Value' because it is not a
variable

Am I right in saying that this is because it is a value type not a
reference type? Is there a 'prettier' way of doing this? As I said,
this was all new to me, so feel free to shoot me down if I'm being
dumb (unlikely though that seems :)

Cheers
 
OK it's not pretty, but I think it might be workable (or I might jsut
be tired and emotional and will regret it all in the morning!)

While it may work, I wouldn't want to use it myself - nullability
within nullability is likely to give developers headaches. If you ever
want a genuinely quad-state value, I'd probably suggest using a struct
with all four values effectively encapsulated. That could use a bool?
internally with another bool, but expose all aspects as straight
Boolean properties with appropriate names. Can't say I've ever found a
need though :)
Incidentally, I noticed (this is the first time I have been playing
with nullable and structs) that I can't say

likesCSharp.Value.boolValue = true;

as the compiler tells me ...
Error 1 Cannot modify the return value of
'System.Nullable<nullabletest.Troolean>.Value' because it is not a
variable

Am I right in saying that this is because it is a value type not a
reference type?

Yes. The Value property returns a copy of the value - changing that
copy wouldn't help you at all.
Is there a 'prettier' way of doing this? As I said,
this was all new to me, so feel free to shoot me down if I'm being
dumb (unlikely though that seems :)

Using the current scheme, you'd have to set Value to a new value. You
could expose three constants:

Troolean.True
Troolean.False
Troolean.NotSet

(or something similar)

Jon
 
While it may work, I wouldn't want to use it myself - nullability
within nullability is likely to give developers headaches. If you ever
want a genuinely quad-state value, I'd probably suggest using a struct
with all four values effectively encapsulated. That could use a bool?
internally with another bool, but expose all aspects as straight
Boolean properties with appropriate names. Can't say I've ever found a
need though :)
Yeah - the dual-layer nullability hurt my brain too - although it
wasn't really exposed to a consumer of the object, which is either
null or has a value of null, true or false.
I have come across situations where this is a requirement (although I
have implemented using enumeration) for example, on a (lengthy)
questionnaire which could be saved while partially complete; the
answers to questinos which had not yet been asked needed to be saved
differently to those that had been answered, but the answer was 'Not
Applicable'. Of course, using the Troolean would give you a problem
persisting to the DB too.
Using the current scheme, you'd have to set Value to a new value. You
could expose three constants:

Troolean.True
Troolean.False
Troolean.NotSet

(or something similar)

Jon
Yeah - maybe I'll go back to the drawing board on this :)
Though by past experience, I'll suddenly discover that .Net 7.2
includes a Troolean type ;)
Cheers
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top