using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApplication1
public static class Program
static TResult? NullConditionals<TSource, TResult>(this TSource? source, Func<TSource, TResult?> selector)
return source == null ? (TResult?)null : selector(source.Value);
static TResult NullConditional<TSource, TResult>(this TSource? source, Func<TSource, TResult> selector)
return source == null ? null : selector(source.Value);
static TResult? NullConditionals<TSource, TResult>(this TSource source, Func<TSource, TResult> selector)
return source == null ? null : (TResult?) selector(source);
static TResult? NullConditionals<TSource, TResult>(this TSource source, Func<TSource, TResult?> selector)
return source == null ? null : selector(source);
static TResult NullConditional<TSource, TResult>(this TSource source, Func<TSource, TResult> selector)
return source == null ? null : selector(source);
static TSource? AsNullable<TSource>(this TSource source)
public static void Main(string[] args)
Func<int, int> f2 = f.Memoize();
.NullConditional(x => x.rg)
.NullConditional(x => x.mae)
.NullConditionals(x => x.idade) ?? 50;
public static void MainFlatten()
var list = new List<object>()
Console.WriteLine(string.Join(", ", list.Flatten()));
Console.WriteLine(string.Join(", ", list.Flatten2().Take(4)));
static IEnumerable<object> Flatten(this IEnumerable source)
foreach (var e in source)
foreach (var i in Flatten((IEnumerable)e))
static IEnumerable<object> Flatten2(this IEnumerable source)
var e = source.GetEnumerator();
var stack = new Stack<IEnumerator>();
while ((next = e.MoveNext()))
if (e.Current is IEnumerable)
stack.Push(((IEnumerable)e.Current).GetEnumerator());
var d = (e as IDisposable);
if (d != null) d.Dispose();
foreach (var x in stack.Concat(new[] { e }).OfType<IDisposable>())
return (int) Math.Pow(x, 3);
static Func<T1, TResult> Memoize<T1, TResult>(this Func<T1, TResult> function)
var dic = Enumerable.Repeat(new { _result = default(TResult), _insertedAt = default(DateTime) } , 0).ToDictionary(x => new { _arg1 = default(T1) });
var value = new { _result = default(TResult), _insertedAt = default(DateTime) };
var key = new { _arg1 = arg1 };
if (!dic.TryGetValue(key, out value))
return (dic[key] = new { _result = function(arg1), _insertedAt = DateTime.Now })._result;