A fairly basic problem for a change. Given a class such as this:
public class X
{
public T A;
public T B;
public T C;
...
// (other fields, properties, and methods are not of interest here)
}
I am looking for a concise way to code a method that will return all A
, B
, C
, ...
that are not null in an enumerable collection. (Assume that declaring these fields as an array is not an option.)
public IEnumerable<T> GetAllNonNullABCs(this X x)
{
// ?
}
The obvious implementation of this method would be:
public IEnumerable<T> GetAllNonNullABCs(this X x)
{
var resultSet = new List<T>();
if (x.A != null) resultSet.Add(x.A);
if (x.B != null) resultSet.Add(x.B);
if (x.C != null) resultSet.Add(x.C);
...
return resultSet;
}
What's bothering me here in particular is that the code looks verbose and repetitive, and that I don't know the initial List
capacity in advance.
It's my hope that there is a more clever way, probably something involving the ??
operator? Any ideas?
Note about the chosen answer:
I finally went for a mix of both Bryan Watts' and dtb's answers that allows for a clear separation of defining the set of properties A
,B
,C
,...
and the filtering of the non-null subset:
(1) Definition of the set of included fields/properties:
IEnumerable<T> AllABCs(this X x)
{
return new[] { x.A, x.B, x.C, ... };
}
Or alternatively:
IEnumerable<T> AllABCs(this X x)
{
yield return x.A;
yield return x.B;
yield return x.C;
...
yield break;
}
(2) Returning only non-null values:
IEnumerable<T> ThatAreNotNull(this IEnumerable<T> enumerable)
{
return enumerable.Where(item => item != null);
}
IEnumerable<T> AllNonNullABCs(this X x)
{
return AllABCs().ThatAreNotNull();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// goal reached; it won't get shorter and clearer than this, IMO!
}