views:

188

answers:

3

We have come across a scenario where we need to track the setting and unsettling of a nullable type.

so something like

int? value

if(value.isSet())
{
  addTocollection();
}

we would also need a clear function

value.clear();

The concept is that the data has an extra state that is the set state.

so NULL(set) and NULL(unset) have different meanings. and then you have the value (set) for most cases and the value(unset) (this last case would have no meaning)

is there a way using extension methods or some other pattern that could solve this problem. my current thought is that we will have to revert to an extended class of some sort.

+2  A: 

You can control the nullable type with extension methods - ie: add methods to work with it, etc.

However, at some point, when you start adding behavior to an object like this, the object itself really starts feeling more like it should be in a class of its own. Nullable<T> is nice since it's really still one value - just a value that can be null. It still doesn't have behavior in and of itself.

If you want to add custom behavior, filtering, events for tracking, etc., then I'd consider making your own custom type for this.

Reed Copsey
@Bluephlame: Also, you can't make an extension method that alters the value of the nullable `int` (this is a good thing).
280Z28
I very much agree.
Reed Copsey
A: 

Here is an example.

    public static class NullableInt32Extensions
    {
     public static Boolean IsSet(this Nullable<Int32> value)
     {
      return value.HasValue;
     }  
    }
ChaosPandion
This won't work (the second). You're passing a value type by value in an extension method, so you're nulling out a copy.
Reed Copsey
LOL, I was hoping to make a ghost edit before anyone noticed.
ChaosPandion
+1  A: 

I'm trying to understand what you're after. I think it is something like the below (Dump is from LINQPad, just think Console.WriteLine). Overall, I don't think this is a good idea, because you provide something obscure that does not work as expected. Unless I mis-understand what you want.

void Main()
{
    int? x = null;
    var wrap = new NullableWrapper<int>( x );

    wrap.HasBeenSet.Dump();  // false
    wrap.HasValue.Dump();   // false

    wrap = 10;

    wrap.HasBeenSet.Dump();  // true
    wrap.HasValue.Dump();    // true
    wrap.Value.Dump();       // 10

    int? y = wrap;

    y.HasValue.Dump();   // True
    y.Value.Dump();      // 10

    wrap = null;
    wrap.HasBeenSet.Dump();  // Does now work like expected => bad
}

public class NullableWrapper<T> where T : struct
{
  private Nullable<T> _impl;
  private bool _hasBeenSet = false;

  public NullableWrapper( Nullable<T> t )
  {
    _impl = t;
    _hasBeenSet = t.HasValue;
  }

  public bool HasBeenSet
  {
    get { return _hasBeenSet; }
  }

  public bool HasValue
  {
    get { return _impl.HasValue; }
  }

  public T Value
  {
    get { return _impl.Value; }
    set { _impl = value; _hasBeenSet = true; }
  }

  public void Clear()
  {
    _hasBeenSet = false;
  }

  public static implicit operator Nullable<T>( NullableWrapper<T> lhs )
  {
    return lhs._impl;
  }

  public static implicit operator NullableWrapper<T>( T rhs )
  {
    return( new NullableWrapper<T>( rhs ) );
  }
}
JP Alioto
That is essentially what i want and i think a wrapper will work, if i can make it easy to use.for instance is there any way i can implictly convert the NullableWrapper such as.NullableWrapper<int> wrap = 123;instead of the = new NullableWrapper<int>(123)
Bluephlame
This is shorter "var wrap = Int.Create(x);" I hope this is much better.Here is a rewrite of @JP function.int? x = null;var wrap = Int.Create(x);And for the class public class Int { private Int() { } public static NullableWrapper<int> Create(int? x) { return new NullableWrapper<int>(x); } }Now you can have a shorter.
Jonathan Shepherd