using System.Collections.Generic;
using System.Linq.Expressions;
public static void Main()
var sourceList = new List<Person>
new Person{FirstName = "John", LastName = "Doe", Email = "Jdoe@sample.com"},
new Person{FirstName = "Jane", LastName = "Doe", Email = "JaneDoe@sample.com"},
new Person{FirstName = "John", LastName = "Adams", Email = "JAdams@sample.com"},
new Person{FirstName = "Jane", LastName = "Adams", Email = "JanAdams@sample.com"}
var searcher = new GhettoSearcher<Person>()
.Include(source => source.FirstName)
.Include(source => source.LastName);
var result = searcher.Search(sourceList, term).ToList();
OutputResult(term, result);
result = searcher.Search(sourceList, term).ToList();
OutputResult(term, result);
result = searcher.Search(sourceList, term).ToList();
OutputResult(term, result);
private static void OutputResult(string term, List<Person> results)
Console.WriteLine($"The term \"{term}\" returned {results.Count} results:");
foreach (var result in results)
Console.WriteLine($"- {result.FirstName} {result.LastName} ({result.Email})");
public class GhettoSearcher<T>
private readonly List<Expression<Func<T, object>>> _maps = new List<Expression<Func<T, object>>>();
public IEnumerable<T> Search(IEnumerable<T> source, string term)
return source.Where(item => Combine(item).Contains(term));
public GhettoSearcher<T> Include(Expression<Func<T, object>> property)
if (_maps.Contains(property))
throw new ArgumentException("Already defined");
private string Combine(T input)
var sb = new StringBuilder();
foreach (var map in _maps)
sb.AppendFormat("{0} ", map.Compile()(input));
return sb.ToString().ToLower().Trim();
public string FirstName {get;set;}
public string LastName {get;set;}
public string Email {get;set;}