Created
July 28, 2016 13:47
-
-
Save binki/f3d1eac2267429ebe0d9d4081f622189 to your computer and use it in GitHub Desktop.
Fun with C# expressions and maybe a way to SQL?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Linq.Expressions; | |
namespace ExpressionsFun | |
{ | |
static class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// Following is not allowed, so use a chaining hack from https://blogs.msdn.microsoft.com/mitsu/2010/03/02/c-4-expressions-blocks-part-i/ | |
// instead. | |
//Expression<Func<int>> expression1 = () => | |
//{ | |
// Console.WriteLine("hi"); | |
// Console.WriteLine("there?"); | |
// return 2; | |
//}; | |
var y = Block( | |
() => Console.WriteLine("hi"), | |
() => Console.WriteLine("there")); | |
// Output: | |
// | |
// hi | |
// there | |
Expression.Lambda<Action>(y).Compile()(); | |
// Output: | |
// | |
// BEGIN | |
// PRINT 'hi'; | |
// PRINT 'there'; | |
// END | |
Console.WriteLine(y.ToSql()); | |
} | |
static BlockExpression Block(params Expression<Action>[] statements) | |
{ | |
return Expression.Block( | |
from e in statements | |
select e.Body); | |
// Output: | |
} | |
static string ToSql(this BlockExpression blockExpression) | |
{ | |
return "BEGIN\n" | |
+ string.Join("\n", from expression in blockExpression.Expressions select expression.ToSql()) + "\n" | |
+ "END\n"; | |
} | |
static string ToSql(this Expression expression) | |
{ | |
switch (expression.NodeType) | |
{ | |
case ExpressionType.Call: | |
{ | |
var callExpression = (MethodCallExpression)expression; | |
if (callExpression.Method == ((Action<string>)Console.WriteLine).Method) | |
return $"PRINT {callExpression.Arguments.Single().ToSql()};"; | |
} | |
break; | |
case ExpressionType.Constant: | |
{ | |
var constantExpression = (ConstantExpression)expression; | |
if (constantExpression.Type == typeof(string)) | |
return $"'{constantExpression.Value.ToString().Replace("'", "''")}'"; | |
} | |
break; | |
} | |
throw new Exception($"Unsupported code: {expression}"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment