8

Is there a way to refer to a property name with a variable?

Scenario: Object A have public integer property X an Z, so...

public void setProperty(int index, int value)
{
    string property = "";

    if (index == 1)
    {
        // set the property X with 'value'
        property = "X";
    }
    else 
    {
        // set the property Z with 'value'
        property = "Z";
    }

    A.{property} = value;
}

This is a silly example so please believe, I have an use for this.

DontVoteMeDown
  • 21,122
  • 10
  • 69
  • 105
  • It is hard to understand what you're trying to accomplish. – Dennis Traub Nov 08 '12 at 15:30
  • You can do that using System.Reflection Refer to this http://stackoverflow.com/questions/619767/net-reflection-set-object-property for example. – Rev Nov 08 '12 at 15:32
  • 2
    I'm rather curious as to why you would do something like this instead of using a property like a property? – Jared Nov 08 '12 at 15:33
  • @Jared If it is possible, you should believe that it can be useful. – DontVoteMeDown Nov 08 '12 at 15:36
  • I think anything can be useful give the right circumstanced, but I'm curious as to the reason. Are you trying to set the property value if it IS a specific property? A little context might shed some light on what the code above is attempting – Jared Nov 08 '12 at 15:39
  • @DontVoteMeDown It's certainly possible, and there are situations in which it's appropriate, but they're rare. Reflection is frequently mis-used by those who simply don't know how to design their application properly in the first place. By asking you more about why you are attempting to do this it will determine whether he tells you how to use reflection to solve this problem, or how to avoid having this type of problem in the first place through good design. – Servy Nov 08 '12 at 15:49
  • @DontVoteMeDown If you're only trying to postpone the act of setting the property, see my answer. – gotopie Nov 08 '12 at 15:54
  • 1
    @T.Todua totally. Now that I got more used to extremely complex reflection since I've posted this, I realize how they overlooked this question. – DontVoteMeDown Sep 20 '17 at 11:54

4 Answers4

33

Easy:

a.GetType().GetProperty("X").SetValue(a, value);

Note that GetProperty("X") returns null if type of a has no property named "X".

To set property in the syntax you have provided just write an extension method:

public static class Extensions
{
    public static void SetProperty(this object obj, string propertyName, object value)
    {
        var propertyInfo = obj.GetType().GetProperty(propertyName);
        if (propertyInfo == null) return;
        propertyInfo.SetValue(obj, value);
    }
}

And use it like this:

a.SetProperty(propertyName, value);

UPD

Note that this reflection-based method is relatively slow. For better performance use dynamic code generation or expression trees. There are good libraries that can do this complex stuff for you. For example, FastMember.

tukaef
  • 9,074
  • 4
  • 29
  • 45
  • neither one of these work for my dynamic variable. It is a Dapper object. `data.GetType()` throws an error. – Samuel Thompson Mar 16 '20 at 17:15
  • @tukaef would You please elaborate on why GetType() is necessary in the code? I can see that it is, I just do not understand why I cannot get a property of an object directly, why do I need the GetType() method as well? Please provide a link or an explanation, thanks in advance! – Viktor Nov 18 '21 at 09:29
5

I think you mean reflection:

PropertyInfo info = myObject.GetType().GetProperty("NameOfProperty");
info.SetValue(myObject, myValue);
The Codesee
  • 3,714
  • 5
  • 38
  • 78
LightStriker
  • 19,738
  • 3
  • 23
  • 27
4

Not in the way your suggesting, but yes it is doable. You could use a dynamic object (or even just an object with a property indexer) e.g.

string property = index == 1 ? "X" : "Z";
A[property] = value;

Or alternatively by using Reflection:

string property = index == 1 ? "X" : "Z";
return A.GetType().GetProperty(property).SetValue(A, value);
James
  • 80,725
  • 18
  • 167
  • 237
  • this does not work for my dynamic variable. It is a Dapper object. `data.q1` works, but `data["q1"]` does not work. that throws an error. – Samuel Thompson Mar 16 '20 at 17:18
0

It's hard for me to understand what you're trying to achieve... if you're trying to determine the property and value separately, and at different times, you can wrap the act of setting the property inside a delegate.

public void setProperty(int index, int value)
{
    Action<int> setValue;

    if (index == 1)
    {
        // set property X
        setValue = x => A.X = x;
    }
    else
    {
        // set property Z
        setValue = z => A.Z = z;
    }

    setValue(value);
}
gotopie
  • 2,594
  • 1
  • 20
  • 23