Get property name inside setter

2019-03-22 18:57发布

问题:

I want to preserve a property between postbacks in an ASP.Net application. Currently doing this:

public int MyIndex
{
    get
    {
        return (int)Session[ToString() + "MyIndex"];
    }
}

but would prefer something like:

public int MyIndex
{
    get
    {
        return (int)Session[ToString() + #code_that_returns_property_name#];
    }
}

Setter omitted, but it just pushes value into Session using the same string. Is there some way to use reflection, or a different better solution?

回答1:

public static int Dummy {
    get {
        var propertyName = MethodBase.GetCurrentMethod().Name.Substring(4);
        Console.WriteLine(propertyName);
        return 0;
    }
}


回答2:

Using CallerMemberName is a lot faster and it can be copied and pasted easily for additional properties.

private static object GetSessionValue([CallerMemberName]string propertyName = "") 
{
    return Session[propertyName];
}

private static void SetSessionValue(object value, [CallerMemberName]string propertyName = "") 
{
    Session[propertyName] = value;
}

public int MyIndex
{
    get { return (int)GetSessionValue(); }
    set { SetSessionValue(value); }
}


回答3:

No, there isn't a simple way to do what you want to do. I think you are much better off with the code you have already written.

Edit: This answer has received quite a few downvotes and I do understand why. While it is possible to do what the OP wants to do perhaps we should all stop and think whether or not it is advisable to do so. To paraphrase the immortal words of Dr. Ian Malcom, just because you can do something doesn't mean you should.



回答4:

You can use MethodInfo.GetCurrentMethod().Name to return the name of the current method:

public int MyIndex
{
    get
    {
        return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name];
    }
}

Since properties are implemented as methods under the hood, that will return a name like "get_MyIndex". If you don't want the "get_" part, you can substring out a few characters:

public int MyIndex
{
    get
    {
        return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name.Substring(4)];
    }
}


回答5:

You can use an expression tree to get the member name. It's a bit of a hock but it works. Here is the code.

private string GetPropertyName<TValue>(Expression<Func<BindingSourceType, TValue>> propertySelector)
{
    var memberExpression = propertySelector.Body as MemberExpression;
    if (memberExpression != null)
    {
        return memberExpression.Member.Name;
    }
    else
    {
       return string.empty;    
    }
}

With that code you can do the following

return (int)Session[ToString() + GetPropertyName(MyIndex)];

Code ruthlessly stolen from Romain's answer on the following thread

  • Get class property name


回答6:

You should rather use the ViewState property of your control:

public int MyIndex {
    get { 
        object index = ViewState["MyIndex"];
        return (null == index) ? -1 : (int)index;
    }
    set {
        ViewState["MyIndex"] = value;
    }
}