/// <summary> /// Cria a expressão de acesso ao indexador. /// </summary> /// <param name="instance"></param> /// <param name="indexerToken"></param> /// <returns></returns> private Expression CreateIndexerAccessExpression(Expression instance, IndexerToken indexerToken) { return(Expression.Dynamic(Microsoft.CSharp.RuntimeBinder.Binder.GetIndex(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None, typeof(DynamicPropertyAccessExpressionBuilder), new[] { Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.None, null), Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.Constant | Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.UseCompileTimeType, null) }), typeof(object), new Expression[] { instance, indexerToken.Arguments.Select <object, ConstantExpression>(new Func <object, ConstantExpression>(Expression.Constant)).First <ConstantExpression>() })); }
/// <summary> /// Recupera as informações do membro a partir do token do indexador. /// </summary> /// <param name="token"></param> /// <param name="targetType"></param> /// <returns></returns> private static MemberInfo GetMemberInfoFromIndexerToken(IndexerToken token, Type targetType) { PropertyInfo indexerPropertyInfo = targetType.GetIndexerPropertyInfo((from a in token.Arguments select a.GetType()).ToArray <Type>()); if (indexerPropertyInfo != null) { return(indexerPropertyInfo.GetGetMethod()); } return(null); }
/// <summary> /// Tenta executar o parse para o token do indexador. /// </summary> /// <param name="member"></param> /// <param name="token"></param> /// <returns></returns> private static bool TryParseIndexerToken(string member, out IndexerToken token) { token = null; if (!IsValidIndexer(member)) { return(false); } List <object> arguments = new List <object>(); arguments.AddRange(from a in ExtractIndexerArguments(member) select ConvertIndexerArgument(a)); token = new IndexerToken(arguments); return(true); }
/// <summary> /// Cria a expressão de acesso para o membro. /// </summary> /// <param name="token"></param> /// <param name="instance"></param> /// <returns></returns> public static Expression CreateMemberAccessExpression(this IMemberAccessToken token, Expression instance) { System.Reflection.MemberInfo memberInfoForType = token.GetMemberInfoForType(instance.Type); if (memberInfoForType == null) { throw new ArgumentException(FormatInvalidTokenErrorMessage(token, instance.Type)); } IndexerToken indexerToken = token as IndexerToken; if (indexerToken != null) { IEnumerable <Expression> indexerArguments = indexerToken.GetIndexerArguments(); return(Expression.Call(instance, (System.Reflection.MethodInfo)memberInfoForType, indexerArguments)); } return(Expression.MakeMemberAccess(instance, memberInfoForType)); }
/// <summary> /// Recupera as informações do membro para o tipo informado. /// </summary> /// <param name="token"></param> /// <param name="targetType"></param> /// <returns></returns> private static MemberInfo GetMemberInfoForType(this IMemberAccessToken token, Type targetType) { PropertyToken token2 = token as PropertyToken; if (token2 != null) { return(GetMemberInfoFromPropertyToken(token2, targetType)); } IndexerToken token3 = token as IndexerToken; if (token3 == null) { throw new InvalidOperationException(token.GetType().GetTypeName() + " is not supported"); } return(GetMemberInfoFromIndexerToken(token3, targetType)); }
/// <summary> /// /// </summary> /// <param name="indexerToken"></param> /// <returns></returns> private static IEnumerable <Expression> GetIndexerArguments(this IndexerToken indexerToken) { return(from a in indexerToken.Arguments select Expression.Constant(a)); }