Advertisement
sebbu

Extensions Methods

Oct 16th, 2019 (edited)
439
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.33 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using System.Runtime.CompilerServices;
  7. using System.Text;
  8.  
  9. namespace MSIExport
  10. {
  11.     static class ExtensionMethod
  12.     {
  13.         public static string GetPropertySymbol<T, TResult>(Expression<Func<T, TResult>> expression)
  14.         {
  15.             return String.Join(".",
  16.                 GetMembersOnPath(expression)
  17.                     .Select(m => GetMemberName(m))
  18.                     .Except(new List<String> { null })
  19.                     .Reverse()
  20.                     .ToArray());
  21.         }
  22.         private static IEnumerable<Expression> GetMembersOnPath(Expression expression)
  23.         {
  24.             while (expression != null)
  25.             {
  26.                 yield return expression;
  27.                 expression = getChild(expression);
  28.             }
  29.         }
  30.  
  31.         /* private static dynamic Cast(dynamic obj, Type castTo)
  32.         {
  33.             return Convert.ChangeType(obj, castTo);
  34.         } // */ // requires .NET 4.0
  35.  
  36.         private static string GetMemberName(Expression expression)
  37.         {
  38.             switch (expression.NodeType)
  39.             {
  40.                 case ExpressionType.MemberAccess:
  41.                     return GetMemberName((MemberExpression)expression);
  42.                 case ExpressionType.Call:
  43.                     return GetMemberName((MethodCallExpression)expression);
  44.                 case ExpressionType.Lambda: // starting point
  45.                 case ExpressionType.Parameter: // x => x
  46.                 case ExpressionType.Convert: // if transtypage
  47.                 case ExpressionType.Constant: // for static method
  48.                     return null;
  49.                 default:
  50.                     throw new NotImplementedException();
  51.             }
  52.         }
  53.  
  54.         private static String GetMemberName(MethodCallExpression expression)
  55.         {
  56.             String name = String.Empty;
  57.             if (expression.Method.IsStatic && !expression.Method.IsDefined(typeof(ExtensionAttribute), true))
  58.                 name += expression.Method.DeclaringType.Name + "->";
  59.             name += expression.Method.Name + "()";
  60.             return name;
  61.         }
  62.         private static String GetMemberName(MemberExpression expression)
  63.         {
  64.             return expression.Member.Name;
  65.         }
  66.  
  67.         public static Expression getChild(Expression expression)
  68.         {
  69.             switch (expression.NodeType)
  70.             {
  71.                 case ExpressionType.MemberAccess:
  72.                     return ((MemberExpression)expression).Expression;
  73.                 case ExpressionType.Call:
  74.                     if (((MethodCallExpression)expression).Method.IsStatic)
  75.                         return ((MethodCallExpression)expression).Arguments
  76.                             .SkipWhile(x => x.NodeType == ExpressionType.Constant)
  77.                             // .First(x => x.NodeType == ExpressionType.Parameter || x.NodeType == ExpressionType.Call)
  78.                             .First()
  79.                             ;
  80.                     else
  81.                         return ((MethodCallExpression)expression).Object;
  82.                 case ExpressionType.Lambda:
  83.                     return ((LambdaExpression)expression).Body;
  84.                 case ExpressionType.Convert:
  85.                     return ((UnaryExpression)expression).Operand;
  86.                 case ExpressionType.Parameter:
  87.                     return null;
  88.                 case ExpressionType.Constant:
  89.                     return null;
  90.                 default:
  91.                     throw new NotImplementedException();
  92.             }
  93.         }
  94.         public static Expression<Func<T, Object>> RemoveLast<T>(Expression<Func<T, Object>> expression) where T : class
  95.         {
  96.             if (expression.NodeType == ExpressionType.Lambda)
  97.             {
  98.                 Expression body = ((LambdaExpression)expression).Body;
  99.                 body = getChild(body);
  100.                 return Expression.Lambda<Func<T, Object>>(body, expression.Parameters);
  101.             }
  102.             else throw new NotImplementedException();
  103.         }
  104.  
  105.         public static void Add<T>(this IDictionary<String, String> dict, T obj, Expression<Func<T, Object>> getValue) where T : class
  106.         {
  107.             String key = GetPropertySymbol(getValue);
  108.             Object value = null;
  109.             try
  110.             {
  111.                 value = getValue.Compile().Invoke(obj);
  112.             }
  113.             catch (NullReferenceException)
  114.             {
  115.                 // we (probably) tried to call ToString() or other on a null Object
  116.                 Expression<Func<T, object>> getValue2 = RemoveLast(getValue);
  117.                 key = GetPropertySymbol(getValue2);
  118.                 value = getValue2.Compile().Invoke(obj);
  119.             }
  120.             dict.Add(key, value?.ToString());
  121.         }
  122.  
  123.         public static IEnumerable<string> GraphemeClusters(this string s)
  124.         {
  125.             var enumerator = StringInfo.GetTextElementEnumerator(s);
  126.             while (enumerator.MoveNext())
  127.             {
  128.                 yield return (string)enumerator.Current;
  129.             }
  130.         }
  131.  
  132.         public static string ReverseGraphemeClusters(this string s)
  133.         {
  134.             return string.Join(string.Empty, s.GraphemeClusters().Reverse().ToArray());
  135.         }
  136.  
  137.     }
  138. }
  139.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement