2008-11-07 15 views
7

कहें कि आपके पास कक्षा घोषणा है, उदाहरण के लिए:क्या आप पता लगा सकते हैं कि सी # फ़ील्ड को डिफ़ॉल्ट मान असाइन किया गया है या नहीं?

 
class MyClass 
{ 
    int myInt=7; 
    int myOtherInt; 
} 

अब, प्रतिबिंब (या किसी अन्य माध्यम, उस मामले के लिए) का उपयोग करके जेनेरिक कोड में कोई तरीका है, कि मैं यह समझ सकता हूं कि myInt का डिफ़ॉल्ट मान है सौंपा गया, जबकि myOtherInt नहीं करता है? एक स्पष्ट डिफ़ॉल्ट मान के साथ प्रारंभ होने के बीच अंतर को नोट करें, और इसके अंतर्निहित डिफ़ॉल्ट मान पर छोड़ा जा रहा है (myOtherInt को डिफ़ॉल्ट रूप से 0 तक प्रारंभ किया जाएगा)।

अपने स्वयं के शोध से ऐसा लगता है कि ऐसा करने का कोई तरीका नहीं है - लेकिन मैंने सोचा कि मैं छोड़ने से पहले यहां पूछूंगा।

[संपादित करें]

यहां तक ​​कि शून्य और संदर्भ प्रकारों के साथ मैं उन लोगों के बीच distingush करना चाहता हूं जो शून्य के रूप में छोड़े गए हैं, और जिन्हें स्पष्ट रूप से शून्य के रूप में प्रारंभ किया गया है। ऐसा इसलिए है कि मैं कह सकता हूं कि प्रारंभिक वाले फ़ील्ड "वैकल्पिक" हैं और अन्य फ़ील्ड "अनिवार्य" हैं। फिलहाल मुझे विशेषताओं का उपयोग करके ऐसा करना है - जो मुझे इस मामले में जानकारी की अपनी अनावश्यकता के साथ निगलता है।

+0

मुझे ऐसा नहीं लगता है, प्रतिबिंब का उपयोग करके खुद को सीटीओआर के माध्यम से ट्रेस करने से कम, यह बताते हुए कि कौन सा क्षेत्र छुआ और कौन नहीं है। – Alan

+0

एलन - यह चक्र के सुझाव के समान ही है। किसी भी कारण से आप वास्तविक प्रतिक्रिया पोस्ट नहीं करना चाहते थे? – philsquared

+0

ठीक है, मैंने आपके कोड के आईएल को रिफ्लेक्टर में देखा, फिर मुझे एहसास हुआ कि मुझे बहुत जल्द हॉटफिक्स भेजना है (अर्थ: उचित उत्तर w/प्रतिबिंब कोड के लिए कोई समय नहीं) और सोचा कि मैं इसे सिर्फ एक विचार के रूप में फेंक दूंगा आप गहराई में खोज करने के लिए;) – Alan

उत्तर

18

मैं अपने कोड संकलित और ILDASM में यह लोड और मिल गया इस

.method public hidebysig specialname rtspecialname 
     instance void .ctor() cil managed 
{ 
    // Code size  15 (0xf) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: ldc.i4.7 
    IL_0002: stfld  int32 dummyCSharp.MyClass::myInt 
    IL_0007: ldarg.0 
    IL_0008: call  instance void [mscorlib]System.Object::.ctor() 
    IL_000d: nop 
    IL_000e: ret 
} // end of method MyClass::.ctor 

नोट ldc.i4.7 और stfld int32 dummyCSharp.MyClass::myInt मींट क्षेत्र के लिए डिफ़ॉल्ट मान सेट करने के लिए दिए गए निर्देशों का हो रहा है।

तो इस तरह के असाइनमेंट को वास्तव में एक निर्माता में अतिरिक्त असाइनमेंट स्टेटमेंट के रूप में संकलित किया जाता है।

इस तरह के असाइनमेंट का पता लगाने के लिए, आपको MyClass के कन्स्ट्रक्टर विधि के आईएल पर प्रतिबिंबित करने के लिए प्रतिबिंब की आवश्यकता होगी और stfld (फ़ील्ड सेट?) कमांड देखें।


संपादित करें: यदि मैं स्पष्ट रूप से निर्माता में कुछ काम जोड़ें:

class MyClass 
{ 
    public int myInt = 7; 
    public int myOtherInt; 

    public MyClass() 
    { 
     myOtherInt = 8; 
    } 
} 

जब मैं इसे ILDASM में लोड, मुझे मिल गया इस:

.method public hidebysig specialname rtspecialname 
       instance void .ctor() cil managed 
{ 
    // Code size  24 (0x18) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: ldc.i4.7 
    IL_0002: stfld  int32 dummyCSharp.MyClass::myInt 
    IL_0007: ldarg.0 
    IL_0008: call  instance void [mscorlib]System.Object::.ctor() 
    IL_000d: nop 
    IL_000e: nop 
    IL_000f: ldarg.0 
    IL_0010: ldc.i4.8 
    IL_0011: stfld  int32 dummyCSharp.MyClass::myOtherInt 
    IL_0016: nop 
    IL_0017: ret 
} // end of method MyClass::.ctor 

ध्यान दें कि अतिरिक्त असाइनमेंट मेरे अन्य पर जो मैंने जोड़ा है के बाद ऑब्जेक्ट क्लास के कन्स्ट्रक्टर को कॉल किया गया था।

IL_0008: call  instance void [mscorlib]System.Object::.ctor() 
तो वहाँ तुम्हारे पास है

,

को निर्दिष्टकरने कॉल से पहले किया आईएल में वर्ग के निर्माता वस्तु लिए एक डिफ़ॉल्ट मान काम है।

इसके बाद कुछ भी कक्षा के वास्तविक कन्स्ट्रक्टर कोड के अंदर एक बयान है।

हालांकि अधिक विस्तृत परीक्षण किया जाना चाहिए।

पेज। कि था मज़ा :-)

+0

गंदा को खत्म करना चाहता हूं, लेकिन इसमें कुछ भी हो सकता है - धन्यवाद। मुझे गहराई से देखना होगा (मैंने अभी तक आईएल पर कोई प्रतिबिंब नहीं किया है)। – philsquared

+0

आपके अपडेट का जवाब: कूल - और भी अच्छी तरह से परिभाषित दिखता है। – philsquared

+0

मुझे अपने हाथों पर बहुत अधिक समय लगता था। काम करने के लिए जाना होगा हाहा। – chakrit

4

आप इस व्यवहार के लिए एक नल पूर्णांक विचार करना चाह सकते:

class MyClass 
{ 
    int? myInt = 7; 
    int? myOtherInt = null; 
} 
+0

अच्छा सुझाव। दुर्भाग्यवश मुझे संदर्भ प्रकारों से निपटने की आवश्यकता है और पता चलता है कि शून्य का डिफ़ॉल्ट प्रदान किया गया है या नहीं। ऐसा इसलिए है कि मैं अनिवार्य और वैकल्पिक मानों के बीच अंतर कर सकता हूं। मैं आपको वोट दे रहा हूं क्योंकि यह एक अच्छा जवाब है, भले ही यह मैं नहीं चाहता हूं- और क्यू – philsquared

+0

पर अधिक जानकारी जोड़ना इस दृष्टिकोण को विस्तारित करने के लिए, आप दो जेनेरिक रैपर structs बना सकते हैं: 'अनिवार्य ' और ' वैकल्पिक '। आपको उनके अंदर की जरूरत है एक सार्वजनिक पाठक क्षेत्र (इसलिए वे अपरिवर्तनीय हैं) और दो अंतर्निहित 'टी' से और उसके पास होते हैं। यह थोड़ा भारी हाथ हो सकता है लेकिन यह तकनीकी रूप से एक विकल्प है। – AnorZaken

3

एक डिफ़ॉल्ट मान किसी अन्य की तरह एक मूल्य है।

int explicitly = 0; 
int implicitly; 

दोनों ही मामलों में, आप उन्हें मान 0 है, एक तरह से केवल आपके टाइपिंग की बचत होती है दे: इन दो मामलों के बीच अंतर करने का कोई तरीका नहीं है। कोई जादू "डिफ़ॉल्ट अनियमित मूल्य" नहीं है - वे दोनों शून्य हैं। वे बिल्कुल वही होने के लिए काम करते हैं। हालांकि, तथ्य यह है कि आप इस पर विचार कर रहे हैं यह इंगित करता है कि आप अच्छे विचारों के ट्रैक से गंभीरता से दूर हैं। तुम क्या कर रहे हो? आपकी विशिष्ट आवश्यकता क्या है? आप गलत सवाल पूछ रहे हैं;)

+0

मुझे पता है तुम्हारा क्या मतलब है। हालांकि मुझे लगता है कि मेरे पास वैध उपयोग केस है। मैं कमांड लाइन तर्क, app.config, या यहां तक ​​कि अन्य स्रोतों से मूल्यों को पॉप्युलेट करने के लिए प्रतिबिंब का उपयोग कर रहा हूं। अधिक जानकारी के लिए मेरे प्रश्न अद्यतन देखें। गुणों का उपयोग करना काम करता है, लेकिन इसमें एक रिडंडेंसी का स्तर है जिसमें मैं – philsquared

-1

यदि आप इसे मान निर्दिष्ट करने से पहले एक चर का उपयोग करने का प्रयास करते हैं तो संकलक को चेतावनी उत्पन्न करने के लिए सेट किया जा सकता है। मेरे पास डिफ़ॉल्ट सेटिंग है और यह कैसे व्यवहार करता है।

-2

नीचे दी गई सहायता करता है:

bool isAssigned = (myOtherInt == default(int)); 
+1

नहीं, क्षमा करें। अच्छा प्रयास। इस मामले में डिफ़ॉल्ट (int) 0 होगा, जिसे मैं इसे स्पष्ट रूप से प्रारंभ कर सकता था। – philsquared

1

वैकल्पिक पैरामीटर के लिए एक नल प्रकार का उपयोग मूल्य प्रकारों के लिए काम करना चाहिए। यदि वे वैकल्पिक नहीं हैं तो स्ट्रिंग को खाली करने के लिए भी प्रारंभ किया जा सकता है।

int mandatoryInt; 
int? optionalInt; 

हालांकि यह मुझे थोड़ा गंदे के रूप में मारता है, मैं इसे करने के स्पष्ट तरीके के रूप में गुणों के साथ चिपके रहूंगा। के टुकड़े हैलो -

class myClass 
    { 
     #region Property: MyInt 
     private int _myIntDefault = 7; 
     private bool _myIntChanged = false; 
     private int _myInt; 
     private int MyInt 
     { 
      get 
      { 
      if (_myIntChanged) 
      { 
       return _myInt; 
      } 
      else 
      { 
       return _myIntDefault; 
      } 
      } 
      set 
      { 
      _myInt = value; 
      _myIntChanged = true; 
      } 
     } 

     private bool MyIntIsDefault 
     { 
      get 
      { 
      if (_myIntChanged) 
      { 
       return (_myInt == _myIntDefault); 
      } 
      else 
      { 
       return true; 
      } 
      } 
     } 
     #endregion 
    } 

एक क्षेत्र के लिए कोड के बहुत है कि:

+1

धन्यवाद - लेकिन डकवर्थ को मेरी प्रतिक्रिया देखें, और मेरा प्रश्न अपडेट करें। – philsquared

0

यह दृष्टिकोण संपत्ति प्राप्त/सेट प्रक्रिया का उपयोग करता!

1

हो सकता है यह आसान समाधान नहीं है ...

आप उपयोग कर सकते हैं डे DefaultValue की तरह मान सेट करने के लिए गुण:

आयात System.ComponentModel और System.Reflection

private int myNumber = 3; 
[System.ComponentModel.DefaultValue(3)] 
public int MyNumber 
{ 
    get 
    { 
     return myNumber; 
    } 
    set 
    { 
     myNumber = value; 
    } 
} 

और उसके बाद प्रतिबिंब के साथ डिफ़ॉल्ट मान पुनर्प्राप्त करें:

PropertyInfo prop = this.GetType().GetProperty("MyNumber"); 
MessageBox.Show(((DefaultValueAttribute)(prop.GetCustomAttributes(typeof(DefaultValueAttribute), true).GetValue(0))).Value.ToString()); 
+0

हाँ, यही वह है जो मैं पहले से कर रहा हूं। बस अनावश्यकता – philsquared

+0

डी ओह को कम करना चाहता था।बस कुछ हद तक अधिक सामान्य समाधान जोड़ा गया है जो कि डिफ़ॉल्ट ValueAttribute – plinth

+0

हेह को कम करता है, कम से कम आपने कुछ सीखा है :-) – philsquared

0

आप खेतों को निजी/संरक्षित गुणों में लपेट सकते हैं। यदि आप जानना चाहते हैं कि यह सेट किया गया है या नहीं, तो निजी फ़ील्ड (उदा। _myInt.HasValue()) देखें।

class MyClass 
{ 

    public MyClass() 
    { 
     myInt = 7; 
    } 

    int? _myInt; 
    protected int myInt 
    { 
     set { _myInt = value; } 
     get { return _myInt ?? 0; } 
    } 

    int? _myOtherInt; 
    protected int myOtherInt 
    { 
     set { _myOtherInt = value; } 
     get { return _myOtherInt ?? 0; } 
    } 
} 
1

एक सामान्य संरचना बनाने के बारे में क्या है जिसमें मूल्य और प्रारंभिक ध्वज शामिल है?

public struct InitializationKnown<T> { 
    private T m_value; 
    private bool m_initialized; 

    // the default constructor leaves m_initialized = false, m_value = default(T) 
    // InitializationKnown() {} 

    InitializationKnown(T value) : m_value(value), m_initialized(true) {} 

    public bool initialized { 
     get { return m_initialized; } 
    } 
    public static operator T (InitializationKnown that) { 
     return that.m_value; 
    } 
    // ... other operators including assignment go here 
} 

फिर बस उन सदस्यों के स्थान पर इसका उपयोग करें जिन्हें आपको प्रारंभ करने के बारे में जानने की आवश्यकता है। आलसी भविष्य या वादे पर यह एक सुंदर बुनियादी भिन्नता है।

+0

पहली बार यह वास्तव में बुरा नहीं है। हालांकि, मुझे नहीं लगता कि यह विशेषता तकनीक में बहुत कुछ जोड़ता है - यह केवल "मेटा-डेटा" को रैपर वर्ग में विशेषता से ले जाता है - और अधिक जटिलता जोड़ता है। मैं आपको एक व्यावहारिक सुझाव देने के लिए वोट दूंगा, लेकिन शायद वह मार्ग नहीं जायेगा। धन्यवाद। – philsquared

2

अगर मैं इसे सामान्य रनटाइम सुविधा के रूप में बनाना चाहता हूं तो मैं यही करूँगा। स्केलर प्रकारों के लिए, मैं एक डिफ़ॉल्ट मान विशेषता बनाउंगा और डिफ़ॉल्टता निर्धारित करने के लिए इसका उपयोग करूंगा।

यहाँ काम करने के लिए एक आंशिक समाधान है - मुझे यकीन है कि यह बेहतर हो सकता है, लेकिन मैं सिर्फ यह बाहर हो:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Reflection; 
using System.Linq; 
using System.Data; 


namespace FieldAttribute 
{ 
    [global::System.AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] 
    sealed class DefaultValueAttribute : Attribute 
    { 
     public DefaultValueAttribute(int i) 
     { 
      IntVal = i; 
     } 

     public DefaultValueAttribute(bool b) 
     { 
      BoolVal = b; 
     } 

     public int IntVal { get; set; } 
     public bool BoolVal { get; set; } 

     private static FieldInfo[] GetAttributedFields(object o, string matchName) 
     { 
      Type t = o.GetType(); 
      FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

      return fields.Where(fi => ((matchName != null && fi.Name == matchName) || matchName == null) && 
          (fi.GetCustomAttributes(false).Where(attr => attr is DefaultValueAttribute)).Count() > 0).ToArray(); 
     } 

     public static void SetDefaultFieldValues(object o) 
     { 
      FieldInfo[] fields = GetAttributedFields(o, null); 
      foreach (FieldInfo fi in fields) 
      { 
       IEnumerable<object> attrs = fi.GetCustomAttributes(false).Where(attr => attr is DefaultValueAttribute); 
       foreach (Attribute attr in attrs) 
       { 
        DefaultValueAttribute def = attr as DefaultValueAttribute; 
        Type fieldType = fi.FieldType; 
        if (fieldType == typeof(Boolean)) 
        { 
         fi.SetValue(o, def.BoolVal); 
        } 
        if (fieldType == typeof(Int32)) 
        { 
         fi.SetValue(o, def.IntVal); 
        } 
       } 
      } 
     } 

     public static bool HasDefaultValue(object o, string fieldName) 
     { 
      FieldInfo[] fields = GetAttributedFields(o, null); 
      foreach (FieldInfo fi in fields) 
      { 
       IEnumerable<object> attrs = fi.GetCustomAttributes(false).Where(attr => attr is DefaultValueAttribute); 
       foreach (Attribute attr in attrs) 
       { 
        DefaultValueAttribute def = attr as DefaultValueAttribute; 
        Type fieldType = fi.FieldType; 
        if (fieldType == typeof(Boolean)) 
        { 
         return (Boolean)fi.GetValue(o) == def.BoolVal; 
        } 
        if (fieldType == typeof(Int32)) 
        { 
         return (Int32)fi.GetValue(o) == def.IntVal; 
        } 
       } 
      } 
      return false; 
     } 
    } 

    class Program 
    { 
     [DefaultValue(3)] 
     int foo; 

     [DefaultValue(true)] 
     bool b; 

     public Program() 
     { 
      DefaultValueAttribute.SetDefaultFieldValues(this); 
      Console.WriteLine(b + " " + foo); 
      Console.WriteLine("b has default value? " + DefaultValueAttribute.HasDefaultValue(this, "b")); 
      foo = 2; 
      Console.WriteLine("foo has default value? " + DefaultValueAttribute.HasDefaultValue(this, "foo")); 
     } 

     static void Main(string[] args) 
     { 
      Program p = new Program(); 
     } 
    } 
} 
+0

हाँ, यह मूल रूप से मेरे पास पहले से है। इसे खटखटाए जाने की परेशानी के लिए धन्यवाद। हालांकि, इसके गुण गुणों पर प्रतिबिंबित करना ठीक है। मैं बस देखना चाहता था कि क्या मैं इसे खत्म कर सकता हूं। – philsquared

+0

कड़ाई से बोलते हुए, मैंने वर्तमान में सी # सिंटैक्स (प्रारंभकर्ता) का उपयोग करके defauly सेट किया है, लेकिन यह चिह्नित करने के लिए एक विशेषता है कि फ़ील्ड वैकल्पिक है या नहीं – philsquared

0

यदि आप चाहते हैं तो इस है, तो बाहर कोड तल पर जाँच ।
यह ऑक्सीजन [1] में लिखा गया है, उम्मीद है कि यह कोई समस्या नहीं है।

[1] या डेल्फी प्रिज्म कैसे यह अब कहा जाता है


var inst1 := new Sample(); 
var inst2 := new Sample(X := 2); 

var test1 := new DefaultValueInspector<Sample>(true); 
var test2 := new DefaultValueInspector<Sample>(inst2, true); 

var d := test1.DefaultValueByName["X"]; 

var inst1HasDefault := test1.HasDefaultValue(inst1, "X"); 
var inst2HasDefault := test1.HasDefaultValue(inst2, "X"); 

Console.WriteLine("Value: {0}; inst1HasDefault: {1}; inst2HasDefault {2}", 
        d, inst1HasDefault, inst2HasDefault); 

d := test2.DefaultValueByName["X"]; 

inst1HasDefault := test2.HasDefaultValue(inst1, "X"); 
inst2HasDefault := test2.HasDefaultValue(inst2, "X"); 

Console.WriteLine("Value: {0}; inst1HasDefault: {1}; inst2HasDefault {2}", 
        d, inst1HasDefault, inst2HasDefault); 

आउटपुट:

Value: 1; inst1HasDefault: True; inst2HasDefault False 
Value: 2; inst1HasDefault: False; inst2HasDefault True


uses 
    System.Collections.Generic, 
    System.Reflection; 

type 
    DefaultValueInspector<T> = public class 
    private 
     method get_DefaultValueByName(memberName : String): Object; 
     method get_DefaultValueByMember(memberInfo : MemberInfo) : Object; 
    protected 
     class method GetMemberErrorMessage(memberName : String) : String; 
     method GetMember(memberName : String) : MemberInfo; 

     property MembersByName : Dictionary<String, MemberInfo> 
      := new Dictionary<String, MemberInfo>(); readonly; 

     property GettersByMember : Dictionary<MemberInfo, Converter<T, Object>> 
      := new Dictionary<MemberInfo, Converter<T, Object>>(); readonly; 

     property DefaultValuesByMember : Dictionary<MemberInfo, Object> 
      := new Dictionary<MemberInfo, Object>(); readonly; 
    public 
     property UseHiddenMembers : Boolean; readonly; 

     property DefaultValueByName[memberName : String] : Object 
      read get_DefaultValueByName; 
     property DefaultValueByMember[memberInfo : MemberInfo] : Object 
      read get_DefaultValueByMember; 

     method GetGetMethod(memberName : String) : Converter<T, Object>; 
     method GetGetMethod(memberInfo : MemberInfo) : Converter<T, Object>; 

     method HasDefaultValue(instance : T; memberName : String) : Boolean; 
     method HasDefaultValue(instance : T; memberInfo : MemberInfo) : Boolean; 

     constructor(useHiddenMembers : Boolean); 
     constructor(defaultInstance : T; useHiddenMembers : Boolean);  
    end; 

implementation 

constructor DefaultValueInspector<T>(useHiddenMembers : Boolean); 
begin 
    var ctorInfo := typeOf(T).GetConstructor([]); 
    constructor(ctorInfo.Invoke([]) as T, useHiddenMembers); 
end; 

constructor DefaultValueInspector<T>(defaultInstance : T; useHiddenMembers : Boolean); 
begin 
    var bf := iif(useHiddenMembers, 
        BindingFlags.NonPublic) 
       or BindingFlags.Public 
       or BindingFlags.Instance; 

    for mi in typeOf(T).GetMembers(bf) do 
     case mi.MemberType of 
      MemberTypes.Field : 
      with matching fi := FieldInfo(mi) do 
      begin 
       MembersByName.Add(fi.Name, fi); 
       GettersByMember.Add(mi, obj -> fi.GetValue(obj)); 
      end; 
      MemberTypes.Property : 
      with matching pi := PropertyInfo(mi) do 
       if pi.GetIndexParameters().Length = 0 then 
       begin 
        MembersByName.Add(pi.Name, pi); 
        GettersByMember.Add(mi, obj -> pi.GetValue(obj, nil)); 
       end; 
     end; 

    for g in GettersByMember do 
     with val := g.Value(DefaultInstance) do 
      if assigned(val) then 
       DefaultValuesByMember.Add(g.Key, val); 
end; 

class method DefaultValueInspector<T>.GetMemberErrorMessage(memberName : String) : String; 
begin 
    exit "The member '" + memberName + "' does not exist in type " + typeOf(T).FullName 
     + " or it has indexers." 
end; 

method DefaultValueInspector<T>.get_DefaultValueByName(memberName : String): Object; 
begin 
    var mi := GetMember(memberName); 
    DefaultValuesByMember.TryGetValue(mi, out result); 
end; 

method DefaultValueInspector<T>.get_DefaultValueByMember(memberInfo : MemberInfo) : Object; 
begin 
    if not DefaultValuesByMember.TryGetValue(memberInfo, out result) then 
     raise new ArgumentException(GetMemberErrorMessage(memberInfo.Name), 
            "memberName"); 
end; 

method DefaultValueInspector<T>.GetGetMethod(memberName : String) : Converter<T, Object>; 
begin 
    var mi := GetMember(memberName); 
    exit GetGetMethod(mi); 
end; 

method DefaultValueInspector<T>.GetGetMethod(memberInfo : MemberInfo) : Converter<T, Object>; 
begin 
    if not GettersByMember.TryGetValue(memberInfo, out result) then 
     raise new ArgumentException(GetMemberErrorMessage(memberInfo.Name), 
            "memberName"); 
end; 

method DefaultValueInspector<T>.GetMember(memberName : String) : MemberInfo; 
begin 
    if not MembersByName.TryGetValue(memberName, out result) then 
     raise new ArgumentException(GetMemberErrorMessage(memberName), 
            "memberName"); 
end; 

method DefaultValueInspector<T>.HasDefaultValue(instance : T; memberName : String) : Boolean; 
begin 
    var getter := GetGetMethod(memberName); 
    var instanceValue := getter(instance); 
    exit Equals(DefaultValueByName[memberName], instanceValue); 
end; 

method DefaultValueInspector<T>.HasDefaultValue(instance : T; memberInfo : MemberInfo) : Boolean; 
begin 
    var getter := GetGetMethod(memberInfo); 
    var instanceValue := getter(instance); 
    exit Equals(DefaultValueByMember[memberInfo], instanceValue); 
end; 
-1

Huseyint के सुझाव काम नहीं करता है, क्योंकि आप असाइन नहीं किए गए स्थानीय चर के "उपयोग के लिए 'sp_id ''

+0

कोई जवाब नहीं है .. – nawfal