将方法添加到可空类型

时间:2009-08-21 01:12:50

标签: c# extension-methods design-patterns

我们遇到过一种情况,我们需要跟踪可空类型的设置和不稳定。

类似

int? value

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

我们还需要一个明确的功能

value.clear();

概念是数据具有一个额外的状态,即设置状态。

所以NULL(set)和NULL(unset)具有不同的含义。 然后你有大多数情况下的值(设置)和值(未设置)(这最后一种情况没有意义)

有没有办法使用扩展方法或其他一些可以解决这个问题的模式。 我目前的想法是,我们将不得不恢复某种扩展类。

3 个答案:

答案 0 :(得分:2)

您可以使用扩展方法控制可空类型 - 即:添加使用它的方法等。

然而,在某些时候,当你开始向这样的对象添加行为时,对象本身真的开始感觉更像它应该在它自己的类中。 Nullable<T>很好,因为它实际上仍然是一个值 - 只是一个可以为null的值。它本身仍然没有行为。

如果您想添加自定义行为,过滤,跟踪事件等,那么我会考虑为此制作您自己的自定义类型。

答案 1 :(得分:2)

这是一个例子。

    public static class NullableInt32Extensions
    {
        public static Boolean IsSet(this Nullable<Int32> value)
        {
            return value.HasValue;
        }       
    }

答案 2 :(得分:1)

我正在努力了解你所追求的是什么。我认为它类似于下面的内容(转储来自LINQPad,只是想想Console.WriteLine)。总的来说,我认为这不是一个好主意,因为你提供的东西模糊不清,不能按预期工作。除非我误解你想要的东西。

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 ) );
  }
}