Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting all bool members of an object using reflection

Tags:

c#

reflection

I have a struct that has a ton of named bool members. (Please leave good practices and such out of consideration now for the sake of the example).

I want to randomly set these values to either true or false, just for testing purposes.

How can I do this through reflection?

This is what I have so far:

        Random r = new Random();
        foreach (var bool_field in state.GetType().GetFields().Where(x => x.GetType() == false.GetType()))
        {
            bool_field.SetValue(state, r.Next() % 2 == 0 ? true : false);
        }

Unfortunately, it never enters the loop.

UPDATE 1:

Here is how the SystemState struct looks like, which is the type of the state variable. It is filled with bool auto properties.

public struct SystemState
{
     ...
     public bool CanYouHelpMeOnThisOne { get; set; }
     ...
}

UPDATE 2:

The solution posted below seems nice, but it does not work. The reason is that SystemState is a struct not a class. Therefor it is a Value type not a Reference type, so calling the SetValue method has no effect. After changing SystemState to class, the below solution works perfectly.

Now is there any other way, to achieve this without changing SystemState to class?

like image 687
VSZM Avatar asked Dec 17 '13 01:12

VSZM


People also ask

How does reflection set property value?

To set property values via Reflection, you must use the Type. GetProperty() method, then invoke the PropertyInfo. SetValue() method. The default overload that we used accepts the object in which to set the property value, the value itself, and an object array, which in our example is null.

How do you create an instance with a reflection?

We can use newInstance() method on the constructor object to instantiate a new instance of the class. Since we use reflection when we don't have the classes information at compile time, we can assign it to Object and then further use reflection to access it's fields and invoke it's methods.

What is the use of SetValue?

SetValue(Object, Object, Object[]) Sets the property value of a specified object with optional index values for index properties.

What is reflection in programming C#?

Reflection provides objects (of type Type) that describe assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties.


1 Answers

At first you need to change the Where clause:

x => x.FieldType == false.GetType()

As the type of x is FieldInfo


Since the last OP's edit it's not fields there, but properties. So, you should use GetProperties to get the list of properties, and compare the PropertyType, as x would be PropertyInfo then. Also the SetValue method is gonna to have the other signature.

 foreach (var bool_field in state.GetType()
                                 .GetProperties()
                                 .Where(x => x.PropertyType == false.GetType()))
 {
     bool_field.SetValue(state, r.Next() % 2 == 0 ? true : false, null);
 }

Based on OP's comments, if you do want to access the backing fields, you can use the following code:

var fs = state.GetType()
              .GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
              .Where(x => x.FieldType == typeof(bool));
foreach (var f in fs)
{
    f.SetValue(state, true);
}

The overload of GetFields without arguments returns all the public fields of the current Type. While in your case you need the private ones, so use the Type.GetFields Method (BindingFlags) with the suitable BindingFlags.

like image 126
horgh Avatar answered Sep 27 '22 18:09

horgh