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?

Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208

1 Answers1

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)
sloth
  • 99,095
  • 21
  • 171
  • 219
  • 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 – Nikhil Agrawal Sep 10 '12 at 09:28
  • 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. – sloth Sep 10 '12 at 09:32
  • return in void. It should be string. – Nikhil Agrawal Sep 10 '12 at 11:33
  • 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. – Nikhil Agrawal Sep 10 '12 at 11:48
  • 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.` – Nikhil Agrawal Sep 10 '12 at 12:14
  • @NikhilAgrawal Ensure you have importet `System.Linq.Expressions` – sloth Sep 10 '12 at 12:17
  • Wait wait. I compiled and that error is gone. But what about my `NameOfYourClass`. What will come in that place? – Nikhil Agrawal Sep 10 '12 at 12:20
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/16496/discussion-between-bigyellowcactus-and-nikhil-agrawal) – sloth Sep 10 '12 at 12:22
  • I changed the method to use two generics, so it should work with any class and any property now. – sloth Sep 14 '12 at 10:37
  • Read this answer http://stackoverflow.com/questions/12420466/unable-to-cast-object-of-type-system-linq-expressions-unaryexpression-to-type#comment16699153_12420466 – Nikhil Agrawal Sep 14 '12 at 11:02
  • Ah, forget about that. Thanks for sharing! – sloth Sep 14 '12 at 11:07