Имя свойства лямбды и индекс массива - PullRequest
4 голосов
/ 06 октября 2009

Для следующего лямбда-выражения:

GetPropertyNameAndArrayIndex(() => SomeArray[0])

Я знаю, что вы можете получить имя свойства для выражения. Я также знаю, что вы можете получить индекс массива , используя ConstantExpression и получая доступ к значению Right. У меня вопрос, как вы получаете индекс массива (или правильное значение), когда он не является константой, I.E.,

for (int i = 0; i < 5; i++)
{
    GetPropertyNameAndArrayIndex(() => SomeArray[i])
}

Любая помощь будет принята с благодарностью.

1 Ответ

3 голосов
/ 06 октября 2009

Как уже отмечалось в комментариях; обратите внимание, что данный пример подвержен проблемам с захваченными переменными , если используется асинхронно - но, вероятно, в порядке "как есть".

Чтобы сделать это основательно, нужно множество крайних случаев (или вы можете обмануть и использовать Compile()) - но вот пример, который показывает общие темы (без использования Compile):

using System;
using System.Linq.Expressions;
using System.Reflection;
class Program
{
    static void Main()
    {
        string[] arr = { "abc", "def" };
        for (int i = 0; i < arr.Length; i++)
        {
            Foo(() => arr[i]);
        }
    }
    static object Foo<T>(Expression<Func<T>> lambda)
    {
        object obj = Walk(lambda.Body);
        Console.WriteLine("Value is: " + obj);
        return obj;

    }
    static object Walk(Expression expr)
    {
        switch (expr.NodeType)
        {
            case ExpressionType.ArrayIndex:

                BinaryExpression be = (BinaryExpression)expr;
                Array arr = (Array)Walk(be.Left);
                int index = (int) Walk(be.Right);
                Console.WriteLine("Index is: " + index);
                return arr.GetValue(index);
            case ExpressionType.MemberAccess:
                MemberExpression me = (MemberExpression)expr;
                switch (me.Member.MemberType)
                {
                    case MemberTypes.Property:
                        return ((PropertyInfo)me.Member).GetValue(Walk(me.Expression), null);
                    case MemberTypes.Field:
                        return ((FieldInfo)me.Member).GetValue(Walk(me.Expression));
                    default:
                        throw new NotSupportedException();
                }
            case ExpressionType.Constant:
                return ((ConstantExpression) expr).Value;
            default:
                throw new NotSupportedException();

        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...