C# extension methods for List class.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

namespace Extensions
{
    public static class ListExtensions
    {
        [SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Justification = "This is by design.")]
        public static ReadOnlyCollection<T> AsSafeReadOnly<T>(List<T> self)
        {
            if (self == null)
            {
                return null;
            }

            return self.AsReadOnly();
        }

        public static void ForEach<T>(this IEnumerable<T> self, Action<T> action)
        {
            if (self == null || action == null)
            {
                return;
            }
            foreach (T t in self)
            {
                action(t);
            }
        }

        public static void ForEach<T>(this IEnumerable<T> self, Action<T, int> action)
        {
            if (self == null || action == null)
            {
                return;
            }
            int num = 0;
            foreach (T t in self)
            {
                action(t, num);
                num++;
            }
        }

        public static void ForEach<T>(this IList<T> self, Action<T, bool> action)
        {
            if (self == null || action == null)
            {
                return;
            }

            int num = 0;
            foreach (T t in self)
            {
                action(t, num >= self.Count - 1);
                num++;
            }
        }

        public static ReadOnlyCollection<T> ToSafeReadOnlyCollection<T>(this IEnumerable<T> self) where T : class
        {
            if (self == null)
            {
                return null;
            }

            var ts = new List<T>(
                from _ in self
                where _ != null
                select _
            );

            return ts.AsReadOnly();
        }
    }
}