Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this work?

I was googling trying to find a way to call Control.DataBindings.Add without using a string literal but getting the property name from the property itself, which I think would be less error prone, at least for my particular case, since I normally let Visual Studio do the renaming when renaming a property. So my code would look something like DataBindings.Add(GetName(myInstance.myObject)... instead of DataBindings.Add("myObject".... So I found this:

    static string GetName<T>(T item) where T : class
    {
        var properties = typeof(T).GetProperties();
        if (properties.Length != 1) throw new Exception("Length must be 1");
        return properties[0].Name;
    }

That would be called, assuming I have a property called One, this way: string name = GetName(new { this.One }); which would give me "One". I have no clue why does it work and whether is safe to use it or not. I don't even know what that new { this.One } means. And I don't know on which case could it happens that properties.Length is not 1.

By the way, I just tested to rename my property One to Two and Visual Studio turned new { this.One } into new { One = this.Two }, which when used with the GetName function gave me "One", which make the whole thing useless since the name I would be passing to Control.DataBindings.Add would be still "One" after renaming the property.

like image 425
Juan Avatar asked Jan 20 '23 18:01

Juan


2 Answers

new { this.One } creates an instance of an anonymous type with one Property, which is, because you didn't specify a name, called "One". That's why it works.

if you use new { One = this.Two }, you give the property the name "One". If you would leave out the part "One = ", it would work again.

However, the method you are using might be misunderstood if one does not know how it's intended to be used and if one does not call it using an anonymous type.

There is another way if you don't want to use string literals, here is one of the examples you can find on the web:
http://www.codeproject.com/Tips/57234/Getting-Property-Name-using-LINQ.aspx

like image 187
Botz3000 Avatar answered Jan 28 '23 10:01

Botz3000


No, you do not have to stick to string literals:

public static class ControlBindingsCollectionExtensions
{
   public static void Add<T>(this ControlBindingsCollection instance, Expression<Func<T, object>> property)
    {
        var body = property.Body as UnaryExpression;
        var member = body.Operand as MemberExpression;
        var name = member.Member.Name;
        instance.Add(name);
    }
}

Usage:

Control.DataBindings.Add<MyClass>(m => m.MyProperty);
like image 20
jgauffin Avatar answered Jan 28 '23 10:01

jgauffin