2

我正在从属性调用方法。我必须将属性名称作为该方法的属性传递。我的财产是

string lcl_name = string.Empty;

public string Name 
{
get { return lcl_name; }
set 
    {
        if (lcl_name != value) 
        {
            lcl_name = value;
            Foo_Method(GetCorrectPropertyName(MethodBase.GetCurrentMethod().Name));
        }
}
}

方法是

public string GetCorrectPropertyName(string propertyName)
{
    return propertyName.StartsWith("set_") || propertyName.StartsWith("get_") ? 
           propertyName.Substring(4) : string.Empty;
}

我的前辈说我不应该这样调用反射并将直接字符串传递给方法

Foo_Method("Name");

但在这种情况下,由于它是硬编码的,并且如果属性名称发生更改,则必须相应地更改方法调用。

所以我的问题是,其中哪一个在效率方面会更好?我的前辈们看到的还有什么我没有注意到的吗?

4

1 回答 1

2

也许表达式树可以在这里为您提供帮助。

而不是Foo_Method将属性名称作为字符串

void Foo_Method(string name)
{

}

使用类型参数Expression通过MemberExpression检索属性名称:

void Foo_Method(Expression<Func<NameOfYourClass, String>> exp)
{
    var propertyName = ((MemberExpression)exp.Body).Member.Name;
}

并这样称呼它

public string Name 
{
    get { return lcl_name; }
    set 
    {
        if (lcl_name != value) 
        {
            lcl_name = value;
            // Foo_Method("Foo"); string is bad
            Foo_Method(x => x.Name);
        }
    }   
}

这样,在重命名时Name,您不会破坏您的代码,因为它Foo_Method(x => x.Name)也会被重命名(当然,当使用您的 IDE 重构功能进行重命名时)。


编辑:

要回答您的评论:

如果你真的不能给 Foo_Method 添加一个重载,你当然可以只创建另一个方法:

if (lcl_name != value) 
{
    lcl_name = value;
    Foo_Method(GetPropName(x => x.Name));
}

...

string GetPropName(Expression<Func<NameOfYourClass, String>> exp)
{
    return ((MemberExpression)exp.Body).Member.Name;
}

编辑2:

要回答您的其他评论:

您可以创建一个扩展方法

public static class Extensions
{
    public static string GetPropName<T>(this T t, Expression<Func<T, String>> exp)
    {
        return ((MemberExpression)exp.Body).Member.Name;
    }
}

var propertyName = yourInstace.GetPropName(y => y.Name);

但您不必这样做,因为表达式无需任何实例即可正常工作。

public static class Extensions
{
    public static string GetPropName<T>(Expression<Func<T, String>> exp)
    {
        return ((MemberExpression)exp.Body).Member.Name;
    }
}

var propertyName  = Extensions.GetPropName<YourClass>(y => y.Name);

诀窍是在这里使用泛型。


第一种方法在 VB.Net 中看起来像这样

Public Function GetPropName(Of TClass, TProperty)(exp As Expression(Of Func(Of TClass, TProperty))) as String
    Return DirectCast(exp.Body, MemberExpression).Member.Name
End Function

...

GetPropName(Function(x) x.Name)
于 2012-09-10T09:21:10.823 回答