3

快速问题:

我想显示某些实体的某些属性:

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

    Console.Write(propertyValue);
}

所以我可以简单地这样做:

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

我不确定如何编写DisplayEntity函数以便您可以执行此操作。

回答

根据弗洛里安的回答,我稍微浓缩了它,与 lambda 表达式的东西保持一致:

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));
        });
}
4

3 回答 3

4

像这样:

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));
        }
    }

这将为您提供属性的名称及其值。

更新:

例子

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);

结果

P1: 5
P2: 3
P1: 5

更新: 免责声明:这仅适用于直接在 p 上的属性,其他所有内容都应该被捕获。

更新:

示例 2 - 在一次调用中允许多个属性类型:

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));
        }
    }

测试类:

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

执行:

        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);

结果:

P1: 5
P2: 3
P1: 5
P3: hello
于 2013-08-16T17:10:53.343 回答
1

这似乎以一种非常简单的方式完成了这项工作;

public static void DisplayEntity<T>(T entity, params Func<T, Object>[] parm)
{
    foreach (var func in parm)
        Console.WriteLine(func(entity));
}
于 2013-08-16T17:15:51.083 回答
1

尝试这个:

public void DisplayEntity<TEntity, TProperty>(TEntity entity, params Expression<Func<TEntity, TProperty>>[] properties)
{
  foreach (var propertyValue in properties)
  {
    var m = propertyValue.Compile();
    Console.Write(m(entity));
  }
}
//...
DisplayEntity<Contact, string>(contact, c => c.Name);

虽然这可以让您的代码以某种方式编译和工作,但它相当无用,因为可以通过以下方式实现相同的效果:

public void Display(object property)
{
Console.Write(property);
}
//...
Display(contact.Name);

如果您想坚持使用 lambdas(出于教育目的),也许这会更好:

public void DisplayEntity<TEntity>(TEntity entity, params Expression<Func<TEntity, object>>[] properties)
{
  foreach (var propertyValue in properties)
  {
    var m = propertyValue.Compile();
    Console.Write(m(entity));
  }
}
//...
DisplayEntity<Contact>(contact, c => c.Name, c => c.IsEnabled);
于 2013-08-16T17:04:19.537 回答