A sample of LINQ provider.
using System;
using System.Collections;
namespace LINQSample
{
class Program
{
static void Main(string[] args)
{
var myNumberServer = new MyNumberServer(323, 2);
var query = from a in myNumberServer
where a != 3
select a;
foreach(var item in query)
{
Console.WriteLine(item);
}
}
}
public class MyNumberServer
{
private readonly int _numberToServer;
private readonly int _length;
public MyNumberServer(int init, int length)
{
_numberToServer = init;
_length = length;
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < _length; i++)
{
yield return _numberToServer;
}
}
}
public static class Extensions
{
public static IEnumerable Where(this MyNumberServer source, Func<int, bool> predicate)
{
foreach (int item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
public static IEnumerable Select(this MyNumberServer source, Func<object, object> selector)
{
foreach (var item in source)
{
yield return selector(item);
}
}
public static IEnumerable Cast(this MyNumberServer source)
{
foreach (var item in source)
{
yield return (int)(item);
}
}
}
}
Note: This is a sample from the book “Essential LINQ”.
Dynamic reflection is the classic .Net reflection. Now there is a new pattern called “Static Reflection” which is very popular in some open source code like nHibernate. Static Reflection’s main
benefit is “refactoring” friendly. For example, in the following code snippet, if you use the static relfection and change the property name, it won’t break. If you use the string to locate the property, it will break easily.
//Classic Reflection
var entity = new SampleEntity();
entity.SetValue(entity, "Id", 100); //dynamic binding
entity.SetValue(entity, "Name", "Sample");
//Static Relection
var entity1 = new SampleEntity();
entity1.SetValue(e => e.Id, 100); //early binding
entity1.SetValue(e => e.Name, "Sample");
// Static reflections.cs
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace LinqExpressionSample
{
public class SampleEntity
{
public int Id { get; set; }
public string Name { get; set; }
public void SetValue<T>(T entity, string propertyName, object value)
{
PropertyInfo propertyInfo = typeof (T).GetProperty(propertyName);
propertyInfo.SetValue(entity, value, null);
}
}
public static class Extension
{
public static void SetValue<T>(this T entity, Expression<Func<T, object>> expression, object value)
{
MemberExpression memberExpression = GetMemberExpression(expression);
var propertyInfo = memberExpression.Member as PropertyInfo;
propertyInfo.SetValue(entity, value, null);
}
private static MemberExpression GetMemberExpression<T, TValue>(Expression<Func<T, TValue>> expression)
{
if (expression == null)
{
return null;
}
if (expression.Body is MemberExpression)
{
return (MemberExpression)expression.Body;
}
if (expression.Body is UnaryExpression)
{
var operand = ((UnaryExpression)expression.Body).Operand;
if (operand is MemberExpression)
{
return (MemberExpression)operand;
}
if (operand is MethodCallExpression)
{
return ((MethodCallExpression)operand).Object as MemberExpression;
}
}
return null;
}
}
}
Comments Off
Following utility function EnumToArray takes an enum type and returns an array populated with each enum item. You can tweak the code a little bit to make the function to be EnumToList easily.
The sample code also demonstrates how to use Enumerable.Except to get the delta of two arrays of same type T.
using System;
using System.Collections.Generic;
using System.Linq;
namespace IEnumerableTest
{
public static class Utils
{
public static T[] EnumToArray<T>()
{
Type enumType = typeof(T);
if (enumType.BaseType != typeof(Enum))
{
throw new ArgumentException("T must be a System.Enum");
}
return (Enum.GetValues(enumType) as IEnumerable<T>).ToArray();
}
}
class Program
{
static void Main(string[] args)
{
//Convert Enum type to an array
RoleType[] allRoles = Utils.EnumToArray();
//Use IEnumerable.Except to get part of the array.
RoleType[] localUserRoles = new RoleType[] { RoleType.LocalAdmin, RoleType.LocalUser, RoleType.Guest };
RoleType[] domainUserRoles = allRoles.Except(localUserRoles).ToArray();
}
enum RoleType
{
DomainAdmin,
LocalAdmin,
DomainUser,
LocalUser,
Guest
}
}
}