2011-06-18 10 views
5

Chcę uzyskać wszystkie pola, które mają wartości zerowe ale aint nawet uzyskanie wszelkich polach:dostać pola z refleksji

[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; 
    } 
} 

A potem mam klasy:

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

Ale kiedy przychodzi do

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

następnie otrzymuję 0 pól, powinien znaleźć 2 pola.

Czy typ.getType(). GetFields() jest niewłaściwy w użyciu? czy wysyłam niewłaściwą klasę do klasy bazowej?

Odpowiedz

13

Type.GetFields metody zwraca wszystko pola publiczne. Pola automatycznie generowane przez kompilator są prywatne, dlatego musisz podać poprawną BindingFlags.

type.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic) 
1

Value1 i Value2 w swojej klasie Settings są właściwości zamiast pól, więc trzeba użyć GetProperties() do nich dostęp.

(przy użyciu składni { get; set; } informuje kompilator, że ma właściwości, ale że powinien on generować get i set dla ciebie, wraz z ukrytym prywatnego pola zawierającego dane.)

0

pola generowanego przez kompilator odpowiadający właściwościom swojej klasie mają atrybut CompilerGenerated. Ponadto kompilator wygeneruje metody get i set w zakresie obsługi tych pól, w zależności od deklaracji własności.

Od CompilerGeneratedAttribute MSDN dokumentacji:

Rozróżnia element kompilatora generowane z elementu generowane przez użytkowników. Ta klasa nie może zostać odziedziczona.

Nazwa tych dziedzinach mają format <PropertyName>k_BackingField, że metody set i get nazwy mają format set_PropertyName i get_PropertyName gdzie PropertyName jest nazwą obiektu.

Na przykład klasa Settings jest kompilowany, co następuje:

[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; 
    } 
} 

Jeśli chcesz wykluczyć ten pola oporowe można użyć tej metody:

public IEnumerable<FieldInfo> GetFields(Type type) 
{ 
    return type 
     .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) 
     .Where(f => f.GetCustomAttribute<CompilerGeneratedAttribute>() == null); 
}