2011-06-18 30 views
5

साथ खेतों मैं शून्य मान है कि सभी क्षेत्रों पाने के लिए चाहते हैं, लेकिन मैं किसी भी क्षेत्रों में हो रही है नहीं:प्रतिबिंब

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

और फिर मैं एक वर्ग है:

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

लेकिन जब मैं आता है

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

तो मुझे 0 फ़ील्ड मिलते हैं, इसे 2 फ़ील्ड मिलना चाहिए।

टाइप.get टाइप()। GetFields() का उपयोग करने में गलत है? या मैं गलत वर्ग में बेस क्लास में भेज रहा हूं?

उत्तर

13

Type.GetFields तरीकों सभी रिटर्न सार्वजनिक क्षेत्र आपके लिए कंपाइलर स्वत: जेनरेट करने वाले फ़ील्ड निजी हैं, इसलिए आपको सही BindingFlags निर्दिष्ट करना होगा।

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

Value1 और Value2 अपने Settings वर्ग में नहीं बल्कि खेतों से गुण हैं, ताकि आप उन्हें उपयोग करने के लिए GetProperties() का उपयोग करना होगा।

({ get; set; } वाक्य रचना का उपयोग संकलक है कि आप एक संपत्ति चाहते बताती है, लेकिन है कि यह get और आप के लिए set, एक छिपे हुए निजी क्षेत्र है कि डेटा होता है के साथ उत्पन्न करनी चाहिए।)

0

संकलक अपने वर्ग के गुणों के लिए इसी के द्वारा उत्पन्न क्षेत्रों CompilerGenerated विशेषता है। इसके अलावा संकलक get और set आपकी संपत्ति की घोषणा के आधार पर इन क्षेत्रों को संभालने के तरीकों को उत्पन्न करेगा।

CompilerGeneratedAttribute MSDN प्रलेखीकरण से:

एक उपयोगकर्ता जनित तत्व से एक संकलक-उत्पन्न तत्व अलग करता है। इस वर्ग को विरासत नहीं बनाया जा सकता।

इन क्षेत्रों का नाम प्रारूप <PropertyName>k_BackingField, विधियों set और get नाम प्रारूप set_PropertyName और get_PropertyName जहां PropertyName संपत्ति का नाम है होता है।

उदाहरण के लिए, अपने Settings वर्ग इस प्रकार संकलित किया गया है:

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

आप इस विधि का उपयोग कर सकते हैं, तो आप इस समर्थन फील्ड छोड़ इच्छा:

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