Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get fields with reflection [duplicate]

I want to get all fields that have null values but i aint even getting any fields:

  [Serializable()]
public class BaseClass
{
    [OnDeserialized()]
    internal void OnDeserializedMethod(StreamingContext context)
    {
        FixNullString(this);
    }

    public void FixNullString(object type)
    {
        try
        {
            var properties = type.GetType().GetFields();


            foreach (var property in from property in properties
                                     let oldValue = property.GetValue(type)
                                     where oldValue == null
                                     select property)
            {
                property.SetValue(type, GetDefaultValue(property));
            }
        }
        catch (Exception)
        {

        }
    }

    public object GetDefaultValue(System.Reflection.FieldInfo value)
    {
        try
        {
            if (value.FieldType == typeof(string))
                return "";

            if (value.FieldType == typeof(bool))
                return false;

            if (value.FieldType == typeof(int))
                return 0;

            if (value.FieldType == typeof(decimal))
                return 0;

            if (value.FieldType == typeof(DateTime))
                return new DateTime();
        }
        catch (Exception)
        {

        }

        return null;
    }
}

And then i have a class :

    [Serializable()]
public class Settings : BaseClass
{
    public bool Value1 { get; set; }
    public bool Value2 { get; set; }
}

But when i comes to

 var properties = type.GetType().GetFields();

then i get 0 fields, it should find 2 fields.

Is type.getType().GetFields() wrong to use ? or am i sending in the wrong class to the base class?

like image 269
syncis Avatar asked Jun 18 '11 08:06

syncis


1 Answers

The fields generated by the compiler corresponding to properties of your class have the CompilerGenerated attribute. Also the compiler will generate get and set methods for handling these fields, depending on the declaration of your property.

From CompilerGeneratedAttribute MSDN documentation:

Distinguishes a compiler-generated element from a user-generated element. This class cannot be inherited.

The name of these fields have the format <PropertyName>k_BackingField,the methods set and get names have the format set_PropertyName and get_PropertyName where PropertyName is the name of property.

For example, your Settings class is compiled as follows:

[Serializable]
public class Settings : BaseClass
{
    public Settings(){}

    // Properties
    [CompilerGenerated]
    private bool <Value1>k__BackingField;

    [CompilerGenerated]
    private bool <Value2>k__BackingField;

    [CompilerGenerated]
    public void set_Value1(bool value)
    {
        this.<Value1>k__BackingField = value;
    }

    [CompilerGenerated]
    public bool get_Value1()
    {
        return this.<Value1>k__BackingField;
    } 

    [CompilerGenerated]
    public void set_Value2(bool value)
    {
        this.<Value2>k__BackingField = value;
    }

    [CompilerGenerated]
    public bool get_Value2()
    {
        return this.<Value2>k__BackingField;
    }
}

If you wish exclude this backing fields you can use this method:

public IEnumerable<FieldInfo> GetFields(Type type)
{
    return type
        .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
        .Where(f => f.GetCustomAttribute<CompilerGeneratedAttribute>() == null);
}
like image 186
José Miguel Rodríguez García Avatar answered Sep 23 '22 17:09

José Miguel Rodríguez García