Skip to content

Instantly share code, notes, and snippets.

@ZacharyPatten
Last active September 10, 2020 02:36
Show Gist options
  • Save ZacharyPatten/fe20efb2051a953a7ea9087313ca676d to your computer and use it in GitHub Desktop.
Save ZacharyPatten/fe20efb2051a953a7ea9087313ca676d to your computer and use it in GitHub Desktop.
Experimenting with a "sourceof" operator similar to "nameof" but works on expressions...
using System;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using static Syntax;
public class Program
{
static void Main()
{
int a = 7;
int b = 5;
var source1 = sourceof(() => a > b);
if (source1)
{
Console.Error.WriteLine($"Error: {source1}");
}
var source2 = sourceof(() => 0 < a && a > b);
if (source2)
{
Console.Error.WriteLine($"Error: {source2}");
}
}
}
public static class Syntax
{
public struct Source<T>
{
internal Expression<Func<T>> Expression;
public static implicit operator T(Source<T> source) => source.Expression.Compile()();
public static implicit operator string(Source<T> source) => source.ToString();
public override string ToString() => ExpressionToSource(Expression);
}
#pragma warning disable IDE1006 // Naming Styles
public static Source<T> sourceof<T>(Expression<Func<T>> expression) =>
new Source<T>() { Expression = expression, };
#pragma warning restore IDE1006 // Naming Styles
internal static string ExpressionToSource(Expression expression)
{
// this method would need to be much more elaborate...
if (expression is LambdaExpression lambdaExpression)
{
string expressionString = lambdaExpression.Body.ToString();
expressionString = Regex.Replace(expressionString, @"value\(\p{L}+\+\<\>c__\p{L}+\d+_\d+\)\.", string.Empty);
expressionString = expressionString.Replace("AndAlso", "&&");
return expressionString;
}
else
{
return expression.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment