You can
C#'s collection-initializers are just syntactic-sugar over any method named Add, including extension-methods. Whatever C# syntax you have between each-item's {} will be translated into Add method parameters.
So these two statements are almost identical (There is a slight difference in collection-object-lifetime if an exception is thrown before the initializer completes, but that's not worth worrying about):
// Manually:
Dictionary<String,Foo> dict = new Dictionary<String,Foo>();
dict.Add( "foo1", new Foo(1) );
dict.Add( "foo2", new Foo(2) );
dict.Add( "foo3", new Foo(3) );
dict.Add( "foo4", new Foo(4) );
// Collection-initializer:
Dictionary<String,Foo> dict = new Dictionary<String,Foo>()
{
{ "foo1", new Foo(1) },
{ "foo2", new Foo(2) },
{ "foo3", new Foo(3) },
{ "foo4", new Foo(4) }
};
(This also means that if you thought object-initializers were somehow more-efficient than repetitive calls to .Add() or that they'd even result in C++ constexpr-style compile-time pre-initialization of a collection... well unfortunately you're wrong: collection-initializers always have at least O(n) runtime - if you need more efficient initialization consider using an array-backed data-structure so you can use a pre-init array).
So if you want a conditional initializer, first define the extension method for your collection-type (in this case Dictionary<String,dynamic>) with an extra Boolean condition parameter:
public static class MyDictionaryExtensions
{
public static void Add( this Dictionary<String,dynamic> dict, String key, dynamic value, Boolean condition )
{
if( condition )
{
dict.Add( key, value );
}
}
}
Then you can use it like so:
// Pretend these values are retrieved from a database or something
string firstName = "John";
string lastName = "Smith";
List<string> listHobbies = new List<string> () {"hockey","soccer"};
var dict = new Dictionary<string, dynamic>()
{
{ "firstName", firstName },
{ "lastName" , lastName },
{ "hobbies" , listHobbies, listHobbies.Count > 0 }
};
Better yet: you can make it generic (and you probably shouldn't be using dynamic anyway):
public static class MyDictionaryExtensions
{
public static void Add<TKey,TValue>( this Dictionary<TKey,TValue> dict, TKey key, TValue value, Boolean condition )
where TKey : notnull
{
if( condition )
{
dict.Add( key, value );
}
}
}
Here's screenshot proof of it working in LinqPad:

But why stop there? You're not limited to Boolean condition parameters: you could have some gnarly logic that inspects the state of the this dict, for example, or use a Func<Boolean> to determine the condition at runtime for each item.
There is a minor caveat though: your Add extension method's parameters cannot exactly match the original Add method, otherwise your extension-method won't be selected due to how extension-methods always have lower precedence. You also cannot force-select your extension-method by using an explicit parameter name (collection-initializers don't have named parameters), but you could use a dummy parameter as a third-parameter using a custom struct type (so it has effectively zero cost).
For example, here's an extension I use to succinctly populate Exception.Data's dictionary with information from a failed HttpClient request, which skips responseBody if the value is null:
internal readonly struct OnlyIfBodyIsNotNull
{
}
internal static class DictionaryExtensions
{
public static void Add( this IDictionary exDataDict, String key, String? body, OnlyIfBodyIsNotNull _ )
{
if( body != null )
{
exDataDict.Add( key, body );
}
}
}
Used like so:
public static InvalidOperationException CreateException( String message, HttpResponseHeaders responseHeaders, HttpContentHeaders contentHeaders, String? responseBody = null )
{
return new InvalidOperationException( message )
{
Data =
{
{ "Response.Headers" , responseHeaders.ToString() },
{ "Response.ContentHeaders", contentHeaders .ToString() },
{ "Response.Body" , responseBody , default(OnlyIfBodyIsNotNull) }
}
};
}