Click here to Skip to main content
Click here to Skip to main content
Articles » Languages » C# » General » Downloads
 
Add your own
alternative version
Go to top

LINQ To Google Image and Google Groups

, 8 May 2007
A LINQ Implementation for Google Images/Groups Search
googlelinq.zip
Google
Google
bin
Release
Google.exe
Google.pdb
Google.csproj.user
Properties
expression-tree.JPG
google_linq_10.zip
Common
Google.csproj.user
Group
Image
using System;
using System.Collections.Generic;
using System.Text;

using System.Linq;
using System.Linq.Expressions;

namespace MChen.Linq.GoogleSearch.Common
{
    internal static class ExpressionUtil
    {
        #region methods from DLINQ implementation
        internal static Expression RemoveQuotes(Expression expression)
        {
            while (expression.NodeType == ExpressionType.Quote)
            {
                expression = ((UnaryExpression)expression).Operand;
            }
            return expression;
        }

        internal static Expression RemoveConvert(Expression expression)
        {
            while (expression.NodeType == ExpressionType.Convert)
            {
                expression = ((UnaryExpression)expression).Operand;
            }
            return expression;
        }

        internal static bool IsLambda(Expression expression)
        {
            return (RemoveQuotes(expression).NodeType == ExpressionType.Lambda);
        }

        internal static bool IsMember(Expression expression)
        {
            return expression.NodeType == ExpressionType.MemberAccess ||
                (RemoveConvert(expression).NodeType == ExpressionType.MemberAccess);
        }

        internal static LambdaExpression GetLambda(Expression expression)
        {
            return (RemoveQuotes(expression) as LambdaExpression);
        }

        internal static MemberExpression GetMember(Expression expression)
        {
            if (expression.NodeType == ExpressionType.MemberAccess)
                return expression as MemberExpression;
            return (RemoveConvert(expression) as MemberExpression);
        }

        internal static bool IsSequenceOperatorCall(MethodCallExpression mc)
        {
            Type declaringType = mc.Method.DeclaringType;
            if ((declaringType != typeof(Enumerable)) && (declaringType != typeof(Queryable)))
            {
                return false;
            }
            return true;
        }
        #endregion

        internal static ConstantExpression 
            ProduceConstantExpression<X>(Expression exp)
        {
            try
            {
                return Expression.Constant(
                    Expression.Lambda<Func<X>>(exp, null).Compile().Invoke());
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

    /// <summary>
    /// interface for the visitor pattern
    /// </summary>
    internal interface IExpressionVisitor<T> where T : QueryInfo
    {
        T Visit(Expression exp, T qinfo);

        T VisitSequenceOperatorCall(MethodCallExpression mc, T qinfo);

        T VisitAndAlso(BinaryExpression exp, T qinfo);

        T VisitOrElse(BinaryExpression exp, T qinfo);

        T VisitEquals(BinaryExpression exp, T qinfo);

        T VisitRegularCall(MethodCallExpression exp, T qinfo);

        T VisitLambda(LambdaExpression exp, T qinfo);

        T VisitNot(UnaryExpression exp, T qinfo);

        T VisitGreaterThan(BinaryExpression exp, bool equal, T qinfo);

        T VisitLessThan(BinaryExpression exp, bool equal, T qinfo);
    }

    /// <summary>
    /// base class for Visitors, provide default implementation
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal abstract class ExpressionVisitor<T> : IExpressionVisitor<T>
                                                   where T : QueryInfo
    {
        public virtual T Visit(Expression node, T qinfo)
        {
            switch (node.NodeType)
            {
                //expressions we will implement
                case ExpressionType.AndAlso:
                    return VisitAndAlso((BinaryExpression)node, qinfo);

                case ExpressionType.OrElse:
                    return VisitOrElse((BinaryExpression)node, qinfo);

                case ExpressionType.Equal:
                    return VisitEquals((BinaryExpression)node, qinfo);

                case ExpressionType.Call:
                    return VisitMethodCall((MethodCallExpression)node, qinfo);

                case ExpressionType.Lambda:
                    return VisitLambda((LambdaExpression)node, qinfo);

                case ExpressionType.Not:
                    return VisitNot((UnaryExpression)node, qinfo);

                case ExpressionType.GreaterThan:
                    return VisitGreaterThan((BinaryExpression)node, false, qinfo);

                case ExpressionType.GreaterThanOrEqual:
                    return VisitGreaterThan((BinaryExpression)node, true, qinfo);

                case ExpressionType.LessThan:
                    return VisitLessThan((BinaryExpression)node, false, qinfo);

                case ExpressionType.LessThanOrEqual:
                    return VisitLessThan((BinaryExpression)node, true, qinfo);

                #region NOT IMPLEMENTED EXPRESSION TYPES
                //exp types we don't intend to implement
                case ExpressionType.MemberAccess:
                case ExpressionType.Parameter:
                case ExpressionType.Quote: //this is striped... Visit(((UnaryExpression)node).Operand, qinfo); break;
                case ExpressionType.Constant:
                case ExpressionType.Invoke:
                case ExpressionType.ExclusiveOr:
                case ExpressionType.And:
                case ExpressionType.Or:
                case ExpressionType.Add:
                case ExpressionType.AddChecked:
                case ExpressionType.Coalesce:
                case ExpressionType.Divide:
                case ExpressionType.Modulo:
                case ExpressionType.Multiply:
                case ExpressionType.MultiplyChecked:
                case ExpressionType.NotEqual:
                case ExpressionType.Subtract:
                case ExpressionType.SubtractChecked:
                case ExpressionType.ArrayLength:
                case ExpressionType.Convert:
                case ExpressionType.ConvertChecked:
                case ExpressionType.Conditional:
                case ExpressionType.Funclet:
                case ExpressionType.LeftShift:
                case ExpressionType.RightShift:
                case ExpressionType.TypeAs:
                case ExpressionType.TypeIs:
                case ExpressionType.MemberInit:
                case ExpressionType.Negate:
                case ExpressionType.NegateChecked:
                case ExpressionType.New:
                case ExpressionType.NewArrayInit:
                default:
                    throw new ArgumentException(
                          string.Format("Expression of type {0} not supported.", node.NodeType),
                          "exp");
                #endregion
            }
        }

        #region default implementations for visit methods
        public virtual T VisitAndAlso(BinaryExpression exp, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      exp.NodeType));
        }

        public virtual T VisitOrElse(BinaryExpression exp, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      exp.NodeType));
        }

        public virtual T VisitEquals(BinaryExpression exp, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      exp.NodeType));
        }

        public virtual T VisitMethodCall(MethodCallExpression node, T qinfo)
        {
            Type declaringType = node.Method.DeclaringType;
            if (ExpressionUtil.IsSequenceOperatorCall(node))
            {
                return VisitSequenceOperatorCall(node, qinfo);
            }
            else
            {
                return VisitRegularCall(node, qinfo);
            }
        }

        public virtual T VisitLambda(LambdaExpression exp, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      exp.NodeType));
        }

        public virtual T VisitNot(UnaryExpression exp, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      exp.NodeType));
        }

        public virtual T VisitSequenceOperatorCall(MethodCallExpression node, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      node.NodeType));
        }

        public virtual T VisitRegularCall(MethodCallExpression node, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      node.NodeType));
        }

        public virtual T VisitGreaterThan(BinaryExpression node, bool equal, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      node.NodeType));
        }

        public virtual T VisitLessThan(BinaryExpression node, bool equal, T qinfo)
        {
            throw new NotSupportedException(
                      string.Format("Expression type {0} not supported.",
                      node.NodeType));
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Ming.Chen
Web Developer
United States United States

| Advertise | Privacy | Mobile
Web04 | 2.8.140926.1 | Last Updated 8 May 2007
Article Copyright 2007 by Ming.Chen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid