2009-08-21 7 views
2

Nous avons rencontré un scénario dans lequel nous devons suivre le paramétrage et le déstabilisation d'un type Nullable.Ajout de méthodes aux types nullables

donc quelque chose comme

int? value 

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

nous aurait aussi besoin d'une fonction claire

value.clear(); 

Le concept est que les données a un état supplémentaire qui est l'état de jeu.

donc NULL (ensemble) et NULL (unset) ont des significations différentes. et puis vous avez la valeur (ensemble) pour la plupart des cas et la valeur (unset) (ce dernier cas n'aurait aucune signification)

est-il un moyen d'utiliser des méthodes d'extension ou un autre modèle qui pourrait résoudre ce problème. ma pensée actuelle est que nous devrons revenir à une classe étendue de quelque sorte.

+1

Êtes-vous à la recherche de 'value.HasValue'? –

Répondre

1

J'essaie de comprendre ce que vous recherchez. Je pense que c'est quelque chose comme ci-dessous (Dump est de LINQPad, pensez simplement Console.WriteLine). Dans l'ensemble, je ne pense pas que ce soit une bonne idée, parce que vous fournissez quelque chose d'obscur qui ne fonctionne pas comme prévu. Sauf si je comprends mal ce que tu veux.

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

C'est essentiellement ce que je veux et je pense qu'un emballage fonctionnera, si je peux le rendre facile à utiliser. Par exemple, est-ce que je peux implicitement convertir le NullableWrapper tel que. NullableWrapper wrap = 123; au lieu du = new NullableWrapper (123) – Bluephlame

+0

Ceci est plus court "var wrap = Int.Create (x);" J'espère que c'est beaucoup mieux. Voici une réécriture de la fonction @JP. int? x = null; var wrap = Int.Créer (x); Et pour la classe public class Int {private int () { } de NullableWrapper public static Créer {return new NullableWrapper (x) (int x?); } } Maintenant, vous pouvez avoir un plus court. –

2

Vous pouvez contrôler le type nullable avec des méthodes d'extension - à savoir: ajouter des méthodes pour travailler avec elle, etc.

Cependant, à un moment donné, lorsque vous commencez à ajouter un comportement à un objet comme celui-ci, vraiment l'objet lui-même commence à se sentir plus comme il devrait être dans une classe qui lui est propre. Nullable<T> est sympa car c'est vraiment toujours une valeur - juste une valeur qui peut être nulle. Il n'a toujours pas de comportement en soi.

Si vous souhaitez ajouter un comportement personnalisé, un filtrage, des événements pour le suivi, etc., je considérerais de créer votre propre type personnalisé pour cela.

+1

@Bluephlame: En outre, vous ne pouvez pas faire une méthode d'extension qui modifie la valeur de l'intensible null 'int' (c'est une bonne chose). –

+0

Je suis très d'accord. –

2

Voici un exemple.

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

Cela ne fonctionnera pas (la seconde). Vous passez un type de valeur par valeur dans une méthode d'extension, de sorte que vous annulez une copie. –

+0

LOL, j'espérais faire un ghost edit avant que quelqu'un ne s'en aperçoive. – ChaosPandion

Questions connexes