Do not add to list if it is null c#

11,088

Solution 1

Basically you can't do that with a collection initializer - a collection initializer always adds the same number of elements as there are entries in the comma-separated list. (I suppose you could have a collection whose Add method ignores null values, but Add will definitely be called the same number of times.)

Instead, just use if statements:

if (request.FirstDoc != null)
{
    create.docs.Add(runFunction(request.FirstDoc));
}
// etc

You could always use a local method to simplify that:

public void method (RequestModel request)
{
     var create = new DtoModel { docs = new List<docsModel>() };
     MaybeAdd(request.FirstDoc);
     MaybeAdd(request.SecondDoc);
     MaybeAdd(request.ThirdDoc);

     void MaybeAdd(docsModel doc)
     {
         if (doc != null)
         {
             create.docs.Add(runFunction(doc));
         }
     }
}

I'd originally missed the part about the list itself not being initialized if everything is null. For that, you'd need to change it to check for initialization each time you want to add to it as well:

public void method (RequestModel request)
{
     var create = new DtoModel();
     MaybeAdd(request.FirstDoc);
     MaybeAdd(request.SecondDoc);
     MaybeAdd(request.ThirdDoc);

     void MaybeAdd(docsModel doc)
     {
         if (doc != null)
         {
             if (create.docs == null)
             {
                 create.docs = new List<docsModel>();
             }
             create.docs.Add(runFunction(doc));
         }
     }
}

As an aside, I'd strongly recommend that you start following normal .NET naming conventions, with PascalCase for both types and properties (DocsModel, Method, RunFunction, Docs).

Solution 2

Use Linq

You can accomplish what you want with a little LINQ.

var create = new DtoModel
{
    docs = (new [] 
    { 
        request.FirstDoc, 
        request.SecondDoc, 
        request.ThirdDoc
    })
    .Where( d => d != null)
    .Select( d => runFunction(d))
    .ToList()
};

Longer but easier to read

That's a little hard to read, so I suggest breaking it down a little.

Create a helper method to unroll the requests into an array:

static public T[] CreateArray<T>(params T[] input)
{
    return input;
}

And then write it this way:

var requests = CreateArray
(
    request.FirstDoc, 
    request.SecondDoc, 
    request.ThirdDoc
);

var processedRequests = requests
    .Where( r => r != null)
    .Select( r => runFunction(r));

var create = new DtoModel
{
    docs = processedRequests.ToList()
};

Or if you like using the ternary operator, as in your example, you could do it like this:

public void method (RequestModel request)
{
    var create = new DtoModel
    {
        docs= CreateArray
        (
            request.FirstDoc!= null ? runFunction(request.FirstDoc) :null,
            request.SecondDoc!= null ? runFunction(request.SecondDoc) : null,
            request.ThirdDoc!= null ? runFunction(request.ThirdDoc) : null,
        }
        .Where( d => d != null)
        .ToList()
     };
}

Click here for the full example on DotNetFiddle.

Share:
11,088
Learn AspNet
Author by

Learn AspNet

Updated on June 26, 2022

Comments

  • Learn AspNet
    Learn AspNet almost 2 years

    I am trying to create a list from anonymous function. I want the list to be created if request model properties are not null. Currently, it is adding null to the list

    Code

    public void method (RequestModel request)
    {
     var create = new DtoModel
         {
            docs= new List<docsModel>
             {
               request.FirstDoc!= null ? runFunction(request.FirstDoc) :null,
               request.SecondDoc!= null ? runFunction(request.SecondDoc) : null,
               request.ThirdDoc!= null ? runFunction(request.ThirdDoc) : null,
              }
         };
    }
    

    Currently, it is creating a list of count 3 even if any of the docs are null. I would list to be only created if docs are not null and the list should only contain docs that are not null. There should not be any null values. Request model can have x number of docs.

    I know I can use Linq to remove nulls afterwards but I am looking for a solution where it does not create null elements in list.