2

I am calling a method from a property. I have to pass property name as attribute of that method. My Property is

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

and the method is

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

My seniors say that i should not call Reflection and pass direct string to method this way

Foo_Method("Name");

but in that case since it would be hardcoded and if property name is changed, then method call have to be changed accordingly.

So my question is which one of them would be better in terms of efficiency? Is there something else that my seniors are seeing to which I am oblivious to?

1 Answer 1

2

Maybe Expression Trees can help you here.

Instead of Foo_Method taking the property name as string

void Foo_Method(string name)
{

}

use a parameter of type Expression to retrieve the property name via a MemberExpression:

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

and call it like this

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

This way, when renaming Name, you don't break your code, since Foo_Method(x => x.Name) gets renamed too (when using your IDEs refactoring capabilities for renaming, of course).


Edit:

To answer your comment:

If you really can't add an overload to Foo_Method, you can of course just create another 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;
}

Edit2:

To answer your other comment:

You could create an extension method

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

but you don't have to, since the expressions work fine without any instance.

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

the trick is to use generics here.


The first method would look like this in 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)
Sign up to request clarification or add additional context in comments.

11 Comments

I can't make changes in Foo Method and my question was regarding what should happen before Foo_method that's why that I gave that method name as Foo_method
Well, actually you could just create an overload for Foo_Method, or just create an entire different method for extracting the property name using the technique.
return in void. It should be string.
Lastly I have 2 questions. My GetPropName method was an extension method. So how can I make it into an EM so that all classes can call it and secondly, what is the equivatlent of that in VB.Net as I code in VB.Net.
Firstly what will come in NameOfYourClass. If i add a class name. it will not be applicable to all (i.e. it will not be an extension method) and secondly it shows a compile time error.'System.Windows.Expression' has no type parameters and so cannot have type arguments.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.