Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq Expression to Display

Tags:

c#

linq

Quick Question:

I want to display certain properties of certain entities:

public void DisplayEntity<TEntity>(TEntity entity, params Expression<Func<TEntity, TProperty>> properties)
{
    // access the properties values

    Console.Write(propertyValue);
}

So I can simply do this:

DisplayEntity(Contact contact, c => c.Name);
DisplayEntity(Contact contact, c => c.Name, c => c.Tel);

I'm not sure how to write the DisplayEntity function so that you can do this.

ANSWER

Based on Florian's answer, I slightly condensed it, in keeping with the lambda expression stuff:

static void WriteEntity<T>(T entity, params Expression<Func<T, object>>[] properties)
{
    properties.ToList().ForEach(x =>
        {
            var f = x.Compile();
            MemberExpression me;
            switch (x.Body.NodeType)
            {
                case ExpressionType.Convert:
                case ExpressionType.ConvertChecked:
                    var ue = x.Body as UnaryExpression;
                    me = ((ue != null) ? ue.Operand : null) as MemberExpression;
                    break;
                default:
                    me = x.Body as MemberExpression;
                    break;
            }
            var memberInfo = me.Member;
            Console.WriteLine("{0}: {1}", memberInfo.Name, f(entity));
        });
}
like image 557
Callum Linington Avatar asked Mar 28 '26 01:03

Callum Linington


1 Answers

Like this:

void ShowPropertyName<T1, T2>(T1 p, params Expression<Func<T1, T2>>[] properties)
    {
        foreach (var e in properties)
        {
            var f = e.Compile();
            var memberExpression = e.Body as MemberExpression;
            var memberInfo = memberExpression.Member;
            Console.WriteLine("{0}: {1}", memberInfo.Name, f(p));
        }
    }

This would give you the name of the property and its value.

UPDATE:

Example

class Test
{
    public int P1 { get; set; }
    public int P2 { get; set; }
}

var test = new Test {P1 = 5, P2 = 3};

ShowPropertyName(test, t => t.P1);
ShowPropertyName(test, t => t.P2, t => t.P1);

Result

P1: 5
P2: 3
P1: 5

UPDATE: Disclaimer: This only works for properties directly on p, every thing else should be catched.

UPDATE:

Example 2 - Allowing more then one Property type in one call:

void ShowPropertyName<T1>(T1 p, params Expression<Func<T1, object>>[] properties)
    {
        foreach (var e in properties)
        {
            var f = e.Compile();

            MemberExpression memberExpression;
            if (e.Body is UnaryExpression)
            {
                var unaryExpression = e.Body as UnaryExpression;
                memberExpression = unaryExpression.Operand as MemberExpression;
            }
            else if(e.Body is MemberExpression)
            {
                memberExpression = e.Body as MemberExpression;
            }
            else
            {
                Console.WriteLine("Unsupported Body expression of type {0}", e.Body.GetType());
                return;
            }
            var memberInfo = memberExpression.Member;
            Console.WriteLine("{0}: {1}", memberInfo.Name, f(p));
        }
    }

Test class:

class Test
{
    public int P1 { get; set; }
    public int P2 { get; set; }
    public string P3 { get; set; }
}

Execution:

        var test = new Test {P1 = 5, P2 = 3, P3 = "hello"};

        ShowPropertyName(test, t => t.P1);
        ShowPropertyName(test, t => t.P2, t => t.P1, t=> t.P3);

Result:

P1: 5
P2: 3
P1: 5
P3: hello
like image 140
LunicLynx Avatar answered Mar 29 '26 14:03

LunicLynx