1

I am trying to set the value of a class variable based on a string. I am querying a database for my data which returns a FieldName which should map the name of a variable for my class.

I have been able to get a list of the variables for the class and check if that class variable is equal to the FieldName returned.

However I am unable to set the value for this instance of my class.

Appointment Class:

public class Appointment
{
    public int Id { get; set; }
    public int EmployeeId { get; set; }
    public string EmployeeFullName { get; set; }
    public int SupervisorId { get; set; }
    public string SupervisorFullName { get; set; }
    public string Department { get; set; }
    public int AppointmentType { get; set; }
    public int EmploymentType { get; set; }
}

I initialise an instance of the Appointment Class earlier in this function, however here is the code where I try to assign the value depending on the FieldName.

appointment = new Appointment{//Assigned other values based on other query}

using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
            {
                SqlCommand command = new SqlCommand(querySelectFields, connection);
                connection.Open();

                BindingFlags bindingFlags = BindingFlags.Public |
                                            BindingFlags.NonPublic |
                                            BindingFlags.Instance |
                                            BindingFlags.Static;

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        foreach(FieldInfo field in typeof(Appointment).GetFields(bindingFlags))
                        {
                            // Extracts the field name from original format of "<fieldName>k__BackingField"
                            string tempFieldName = field.Name.Substring(1);
                            string fieldName = tempFieldName.Substring(0, tempFieldName.Length- 16);

                            if ((String)reader["FieldName"] == fieldName)
                            {
                                //This is where it errors
                                field.SetValue(null, int.Parse(reader["SelectValueID"].ToString()));
                            }
                        }
                    }
                }

The error that I am gettings is:

Exception Details: System.Reflection.TargetException: Non-static field requires a target.

I understand that this is caused by putting null as the first parameter in that call, however I cannot seem to find the correct way to do this.

Ideally I would be able to do something like this:

if((String)reader["FieldName"] == fieldName)
{
    appointment.field = int.Parse(reader["Value"].ToString());
}

And that would be the same as:

if((String)reader["FieldName"] == "AppointmentType")
{
    appointment.AppointmentType = int.Parse(reader["Value"].ToString());
}
mullac
  • 693
  • 6
  • 17
  • 1
    Presumably `field.SetValue(appointment, ...)` – ProgrammingLlama Jun 10 '19 at 00:38
  • 1
    fields are not the same as properties and are not the same as variables – Ňɏssa Pøngjǣrdenlarp Jun 10 '19 at 00:41
  • @NatPongjardenlarp so the correct terminology is fields in this case and I just used properties and variables incorrectly? – mullac Jun 10 '19 at 00:52
  • @John your comment worked, Thanks! Not sure how I didn't think of that. If you post your comment as an answer I will mark it as correct if you'd like – mullac Jun 10 '19 at 00:56
  • 1
    Callum Nat's point is that the class you've shown at the top of your post contains Properties (`{ get; set; }`), whereas your code is searching for Fields. see [here](https://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property) for the difference. I'm surprised that my suggestion was the only fix you needed in this case. – ProgrammingLlama Jun 10 '19 at 01:00
  • 1
    Seems like the error message is pretty self-explanatory. And the docs are very clear on the meaning of that first parameter you pass to `GetValue()` or `SetValue()`. For what it's worth, you also should take time to understand the difference between fields, automatic properties, and explicitly-implemented properties. Your code appears to be trying to access the backing field for automatic properties, when probably what you really ought to be doing is just applying the value to the property directly. Your current method won't work for explicitly-implemented properties. – Peter Duniho Jun 10 '19 at 05:53
  • @PeterDuniho Thanks for the explanation. I looked more into fields, automatic properties, and explicitly-implemented properties. I ended up changing my code to use PropertyInfo instead of FieldInfo and that allowed me to remove the logic for extracting the name of the property from the backing field name that FieldInfo returns. I think I was initially confused as I was referring to the Properties as fields/variables in my searching before this question. – mullac Jun 10 '19 at 06:15

0 Answers0