22

I building the following anonymous object:

var obj = new {
    Country = countryVal,
    City = cityVal,
    Keyword = key,
    Page = page
};

I want to include members in object only if its value is present.

For example if cityVal is null, I don't want to add City in object initialization

var obj = new {
    Country = countryVal,
    City = cityVal,  //ignore this if cityVal is null 
    Keyword = key,
    Page = page
};

Is this possible in C#?

3
  • 1
    What would that even mean? The object would be missing a property that the rest of your code expects. What would obj.City mean? Semantically undefined. Commented Jun 7, 2013 at 13:38
  • 1
    In my case I need to create an object which gets serialized into JSON (and send it using RestSharp) - no other manipulation of the object in c#. Based on conditions some of the members should be there, some not. As it is a large object, using accepted answer requires a lot of code. So this question is reasonable. Using some kind of conditional initialization would spare coding Commented Apr 11, 2017 at 10:43
  • Possible duplicate of is it possible to have a conditional field in an anonymous type Commented Nov 30, 2017 at 15:39

4 Answers 4

11

Its not even posibble with codedom or reflection, So you can end up doing if-else if you really need this

if (string.IsNullOrEmpty(cityVal)) {
    var obj = new {
        Country = countryVal,
        Keyword = key,
        Page = page
    };

    // do something
    return obj;
} else {
    var obj = new {
        Country = countryVal,
        City = cityVal,
        Keyword = key,
        Page = page
    };

    //do something 
    return obj;
}
Sign up to request clarification or add additional context in comments.

1 Comment

This works and seems like the only method for an anonymous object. But I would be against it because it adds duplication and complexity. The better way is to adjust the rest of the codebase to handle/ignore null fields.
5

You can't do that.

But what you could do is provide the default value (null?) of those properties.

var obj=  new
            {
                Country= countryVal,
                City = condition ? cityVal : null,
                Keyword = condition ? key : null,
                Page = condition ? page : null
            };

3 Comments

You cannot use conditional initializer in anonymous types
Yes, you can use a ternary operator :|
You can use the ternary operator, but it will still add the field to the object. It will have a null value though. I think this is the way to go and the code should be adjusted to handle or ignore null values.
5

Well you would have if else conditions. But, if you are serilizing this as a JSON object with newtonsoft JSON this could help:

   var json = JsonConvert.SerializeObject(value, Formatting.None,
                    new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore
                    });

4 Comments

There is no mention of JSON on this question other than in a comment from someone else.
that's why i put a "But"
actually, this is very useful. it solved my problem
For those using System.Text.Json::JsonSeriliazerOptions, the property now to use is DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull.
1

You could use an ExpandoObject and a functional extension method.

    pubic class SomeClass

        public dynamic DomainFunction(
            object countryVal = null
          , object cityVal = null
          , object key = null
          , object page = null
        )
        {
            dynamic obj = new ExpandoObject();

            cityVal?.Tee(x => obj.City = x);
            countryVal?.Tee(x => obj.Country = x);
            key?.Tee(x => obj.Keyword = x);
            page?.Tee(x => obj.Page = x);

            return obj;
        }

    }

    public static class FunctionalExtensionMethods{

        public static T Tee<T>(this T source, Action<T> action)
        {
          if (action == null)
            throw new ArgumentNullException(nameof (action));
          action(source);
          return source;
        }

    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.