缩短这个反射属性名称助手方法?

时间:2009-10-16 23:54:27

标签: c# reflection properties

我想要一个静态辅助方法来删除魔术字符串。当然,我可以在TestContainer中打包属性方法,这样就不需要提供TestContainer作为参数。这很好地完成了here

但我想在一个静态类中使用helper方法,以防我后来决定优化我的代码并删除该方法。我设法把它归结为此,但它有点难看(必须提供字符串类型,看起来不是很好)。

任何“表达上帝”都知道更好的方式。请记住,静态类应保持通用,并且不知道有关TestContainer的任何信息(否则它将像提供的链接一样简单)

internal class PropertyNameResolving
{
    internal class TestContainer
    {
        public string LastName { get; set; }
    }

    internal static class BindingHelper
    {
        public static string PropertyName<TObject, TValue>(Expression<Func<TObject, TValue>> propertySelector)
        {
            var memberExpression = propertySelector.Body as MemberExpression;
            if (memberExpression != null) return memberExpression.Member.Name;
            else
            throw new Exception("Something went wrong");
        }
    }

    internal static void Test()
    {
        var t = new TestContainer {LastName = "Hans"};
        Console.WriteLine(BindingHelper.PropertyName<TestContainer, string>(x => x.LastName));
        Console.ReadLine();

    }
}

顺便说一句,输出是“LastName”,可以用来设置绑定。

还有一个问题,我可以安全地删除NULL检查吗?

2 个答案:

答案 0 :(得分:3)

3个选项:

  • 使类具有通用性,并对值
  • 的方法使用推理
  • 使用示例对象推断方法
  • 完全忘记对象类型,只使用示例

这些都显示如下。重新null安全 - 我很想检查表达式类型(你也可以处理方法,顺便说一句) - 更多代码shown here

using System;
using System.Linq.Expressions;
internal class TestContainer
{
    public string LastName { get; set; }
}
static class Program
{
    static void Main()
    {
        var t = new TestContainer {LastName = "Hans"};            
        string s1 = BindingHelper<TestContainer>
                      .PropertyName(x => x.LastName);            
        string s2 = BindingHelper.PropertyName(t, x => x.LastName);
        string s3 = BindingHelper.PropertyName(() => t.LastName);
    }
}
internal static class BindingHelper
{
    public static string PropertyName<TObject, TValue>(TObject template,
        Expression<Func<TObject, TValue>> propertySelector)
    {
        var memberExpression = propertySelector.Body as MemberExpression;
        if (memberExpression != null) return memberExpression.Member.Name;
        else
            throw new Exception("Something went wrong");
    }
    public static string PropertyName<TValue>(
         Expression<Func<TValue>> propertySelector)
    {
        var memberExpression = propertySelector.Body as MemberExpression;
        if (memberExpression != null) return memberExpression.Member.Name;
        else
            throw new Exception("Something went wrong");
    }
}
internal static class BindingHelper<TObject>
{
    public static string PropertyName<TValue>(
        Expression<Func<TObject, TValue>> propertySelector)
    {
        var memberExpression = propertySelector.Body as MemberExpression;
        if (memberExpression != null) return memberExpression.Member.Name;
        else
            throw new Exception("Something went wrong");
    }
}

答案 1 :(得分:1)

因为编译器可以暗示类型参数,所以你不需要在Test()方法中提供任何内容而不改变任何东西。

使用BindingHelper.PropertyName(x =&gt; x.LastName),它应该可以正常工作。

您无法安全地删除空检查,因为您的表达式可能是任何内容,包括方法调用,这不会被视为MemberExpression。