35

I have a very large object with many nullable-type variables. I also have a dictionary which I want to fill up with this object's non-null variables.

The code will look something like this

if (myObject.whatever != null)
{
myDictionary.Add("...",myObject.whatever);
}
if (myObject.somethingElse != null)
{
myDictionary.Add("...",myObject.somethingElse);

...

EDIT (Sorry messed up the code)

When we repeat this for the umpteenth time we get a mess of very long code. Is there some shorter way I could write this mess? I know about the Conditional Operator (aka ?) but that's just for assignments. Is there something like that for adding to a collection?

Aabela
  • 1,408
  • 5
  • 19
  • 28
  • U mean that you only want to ad items that are not null – JohnnBlade Jul 26 '12 at 12:10
  • "I know about the Conditional Operator (aka ?) but that's just for assignments." Where did you get that idea? –  Jul 26 '12 at 12:10
  • @JohnnBlade - Yes. Each has to have a particular key in the dictionary, so i can't use reflection – Aabela Jul 26 '12 at 12:11
  • 1
    _"with this object's non-null variables."_ But you're adding null values. – Tim Schmelter Jul 26 '12 at 12:11
  • 1
    @hvd - Please correct me then, that's the jist of my question – Aabela Jul 26 '12 at 12:11
  • @Aabela It wouldn't help you here, which is why I didn't post it as an answer, but `a ? b : c` is just an expression, it can be used anywhere an expression is needed. –  Jul 26 '12 at 12:12
  • If it's not a performance problem: Why not add everything and then remove what you don't need? – Philipp Jul 26 '12 at 12:11

4 Answers4

53

How about an extension method for your dictionary?

public static void AddIfNotNull<T,U>(this Dictionary<T,U> dic, T key, U value) 
where U : class {
    if (value != null) { dic.Add(key, value); }
}

You could then do this:

myDictionary.AddIfNotNull("...",myObject.whatever);
Botz3000
  • 39,020
  • 8
  • 103
  • 127
9

I'd recommend writing an extension method:

public static class MyExtensions
{
    public static void AddIfNotNull<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
    {
        if ((object)value != null)
            dictionary.Add(key, value);
    }
}

Using (object)value != null ensures that this works as you'd expect with nullable types, (e.g. int?) value types, (e.g. int) and reference types (e.g. SomeClass). If you compare it to default(TValue), then an int of 0 will not be added, even though it's not null. If you include a TValue : class requirement, you can't use Nullable<T> as the type, which it sounds like is your most common usage.

Tim S.
  • 55,448
  • 7
  • 96
  • 122
2

You can make a method that hides your if:

AddIfNotNull(myDictionary, "...", myObject.whatever);

private static void AddIfNotNull<K,T>(
    IDictionary<K,T> myDictionary
,   K key
,   T value) {
    if (value != default(T)) {
        myDictionary.Add(key, value);
    }
}

You can earn some "points for style" by making the method an extension (you need to add it to a static class then):

private static void AddIfNotNull<K,T>(
    this IDictionary<K,T> myDictionary
,   K key
,   T value) {
    if (value != default(T)) {
        myDictionary.Add(key, value);
    }
}

myDictionary.AddIfNotNull(myDictionary, "...", myObject.whatever);

If you know that you are inserting only reference type objects, replace default(T) with null and add a class T constraint to the generic.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Are you sure you want `AddIfNotNull` to not add values that happen to be zero but not null? By the way, there's a missing closing parenthesis after `default(T)`. –  Jul 26 '12 at 12:15
  • @hvd Yes, that's a limitation. An implementation that deals both with classes and nullable values (`int?`, `double?`, etc.) is considerably more complex. – Sergey Kalinichenko Jul 26 '12 at 12:16
  • I think `if (value != null)` would be enough. –  Jul 26 '12 at 12:17
  • @hvd I vaguely remember having issues with that, perhaps in .NET 3.5. I needed to build a somewhat complex null checker that worked with both nullables and classes. – Sergey Kalinichenko Jul 26 '12 at 12:19
  • Null nullables box to `null`, so even if `if (value != null)` has issues (which I'd need to see), `if ((object)value != null)` would still work. –  Jul 26 '12 at 12:22
  • @hvd Very interesting... I just compiled it on mono with `value != null`, and it worked fine. This could have been a resharper's warning about possibly comparing a value type and `null`, I no longer remember: it was at least three years ago. – Sergey Kalinichenko Jul 26 '12 at 12:27
0
public void addToDict(string ?myObj, Dictionary<,> myDict) {
        if (myObj != null)
              myDict.Add("...", myObj);
}

addToDict(myObject.whatever, myDict);
addToDict(myObject.somethignElse, myDict);

etc

Shai
  • 25,159
  • 9
  • 44
  • 67