Useful LINQ Method- GetMemberTypeChain
Recently, I have been working on a custom LINQ provider in C#. In a later post (when I have more time to write) I will go in depth into what I am worked on and what have I learned about writing a LINQ provider. But for now I will present a simple function that simplified part of my work. It is called GetMemberTypeChain (not as bad as it sounds). Given a member access expression it will return the types of all parts of the member access chain. What this means is that given some expression like "myObject.FieldA.FiledB" it will return a list containing the type of each field/property.
In addition to this the method also allows you to filter out compiler created types. When you have a member access which is using a parameter from a FROM clause in a LINQ query the compiler will often createone or more anonymous type. Then unknowlingly the object you are trying to access now has a few anonymous field accesses in front of it. For my purposes I wanted to be able to easily just analyze the types of the relevant parts of the expression.
So without further adieu ... GetMemberTypeChain:
1: private List<Type> GetMemberTypeChain(Expression expression, bool ignoreCompilerGeneratedTypes)
2: {
3: if (expression == null) return null;
4: if (expression.NodeType == ExpressionType.MemberAccess)
5: {
6: MemberExpression memberExpression = (MemberExpression)expression;
7: var result = GetMemberTypeChain(memberExpression.Expression, ignoreCompilerGeneratedTypes);
8: Type type = memberExpression.Type;
9: if (!(ignoreCompilerGeneratedTypes && IsCompilerGeneratedType(type)))
10: result.Add(type);
11: return result;
12: }
13: else if (expression.NodeType == ExpressionType.Constant || expression.NodeType == ExpressionType.Parameter)
14: {
15: var typeList = new List<CustomTypeInfo>();
16: Type type = expression.Type;
17: if (!(ignoreCompilerGeneratedTypes && IsCompilerGeneratedType(type)))
18: typeList.Add(type);
19: return typeList;
20: }
21: else
22: {
23: throw new NotSupportedException("Expression type not supported: " + expression.GetType().FullName);
24: }
25: }
26:
27: private bool IsCompilerGeneratedType(Type type)
28: {
29: var compilerGenerateds = type.GetCustomAttributes(typeof(CompilerGeneratedAttribute), true);
30: return (compilerGenerateds != null && compilerGenerateds.Length > 0);
31: }
Comments
- Anonymous
March 06, 2008
PingBack from http://msdnrss.thecoderblogs.com/2008/03/07/useful-linq-method-getmembertypechain/