मैं यह कैसे जांचूं कि क्या कोई संपत्ति ग # में डायनामिक अनाम प्रकार पर मौजूद है?


122

मेरे पास एक अनाम प्रकार की वस्तु है जो मुझे एक ऐसी विधि से गतिशील के रूप में प्राप्त होती है जिसे मैं उस वस्तु पर मौजूद संपत्ति में जांचना चाहूंगा।

....
var settings = new {
                   Filename="temp.txt",
                   Size=10
}
...

function void Settings(dynamic settings) {
var exists = IsSettingExist(settings,"Filename")
}

मैं IsSettingExist को कैसे लागू करूंगा?



यदि आप अपने आप को गतिशील वस्तुओं पर बहुत हद तक निर्भर पाते हैं, तो शायद यह F # देखने लायक है - वैसे तो अच्छा अवतार
पिओटर कुला

जवाबों:


149
  public static bool IsPropertyExist(dynamic settings, string name)
  {
    if (settings is ExpandoObject)
      return ((IDictionary<string, object>)settings).ContainsKey(name);

    return settings.GetType().GetProperty(name) != null;
  }

  var settings = new {Filename = @"c:\temp\q.txt"};
  Console.WriteLine(IsPropertyExist(settings, "Filename"));
  Console.WriteLine(IsPropertyExist(settings, "Size"));

आउटपुट:

 True
 False

3
यह गतिशील वस्तुओं पर काम नहीं करता है। यह हमेशा अशक्त रहता है।
दुष्ट

@evilom @Shikasta_Kashti क्या आप MVC के साथ इस पद्धति का उपयोग करने का प्रयास कर रहे हैं ViewBag? यदि ऐसा है, तो देखें stackoverflow.com/a/24192518/70345
इयान केम्प

@ Gaspa79। यह एक गैर-असामान्य कोडिंग सम्मेलन है। कुछ लोग सभी बूलियन गुणों पर "इज़" उपसर्ग पसंद करते हैं। इस तरह की संगति आपको एक पहचानकर्ता के पहले कुछ पात्रों (जिसके बाद, इन्टेलिसेन्स काम करता है) का अनुमान लगाने से रोक सकती है, लेकिन इस तरह के मामलों में थोड़ी अजीब अंग्रेजी बनाने की कीमत पर।
solublefish

मुझे लगता है कि Isउपसर्ग का अमान्य क्रिया काल अधिक भ्रमित करने वाला होगा क्योंकि यह उपयोग करने के लिए अन्यथा होगा HasProperty। मैं यह भी कहूंगा कि इस तरह के व्याकरणिक-गलत उपसर्ग का उपयोग करना वास्तव में C♯ में गैर-मुहावरेदार है।
बेन कॉलिन्स 23

ExpandoObject अनाम प्रकार के समान नहीं है। क्या मैं उस बारे में गलत हूं?
ryanwebjackson

37
public static bool HasProperty(dynamic obj, string name)
{
    Type objType = obj.GetType();

    if (objType == typeof(ExpandoObject))
    {
        return ((IDictionary<string, object>)obj).ContainsKey(name);
    }

    return objType.GetProperty(name) != null;
}

objType.GetProperty(name) != null;रिटर्न मौजूद गुणों पर अशक्त
Matas Vaitkevicius

3
objType.GetProperty(name) != nullहमेशा एक लौट आएगा bool, जो (परिभाषा के अनुसार) कभी नहीं हो सकता है null
एलेक्स मैकमिलन

@AlexMcMillan निश्चित नहीं है कि आप किस आयाम में रहते हैं, जहां Type.GetProperty(string)एक नीरव संपत्ति में शून्य के अलावा कुछ भी नहीं मिलता है।
इयान केम्प

2
@IanKemp, AlexMcMillan ने objType.GetProperty (नाम) कहा ! = MatasVaitkevicius टिप्पणी के जवाब में वास्तव में अशक्त
सर्गेई

15

यदि आप सेटिंग्स ऑब्जेक्ट बनाने / पास करने को नियंत्रित कर सकते हैं, तो मैं इसके बजाय एक ExpandoObject का उपयोग करने की सलाह दूंगा।

dynamic settings = new ExpandoObject();
settings.Filename = "asdf.txt";
settings.Size = 10;
...

function void Settings(dynamic settings)
{
    if ( ((IDictionary<string, object>)settings).ContainsKey("Filename") )
        .... do something ....
}

मैं इसे बदल नहीं सकता, क्या मैं ExpendoObject को कास्ट कर सकता हूं?
डेविड एमजेड

6

अनाम प्रकार, के लिए यह काम करता है ExpandoObject, Nancy.DynamicDictionaryया कुछ और कि करने के लिए डाली जा सकती है IDictionary<string, object>

    public static bool PropertyExists(dynamic obj, string name) {
        if (obj == null) return false;
        if (obj is IDictionary<string, object> dict) {
            return dict.ContainsKey(name);
        }
        return obj.GetType().GetProperty(name) != null;
    }

2
महान समाधान। JSON स्ट्रिंग को जॉबजेक्ट में परिवर्तित करते समय मुझे एक और IF स्टेटमेंट जोड़ना होगा .... "अगर (obj Newtonsoft.Json.Linq.JObject है) तो रिटर्न ((Newtonsoft.Json.Linq.Jbbject) obj) .ContainsKey (नाम); "
rr789

1
मेरे लिए भी काम किया। अद्भुत जवाब सेठ रेनो। मैंने यह भी जोड़ा है "अगर (obj Newtonsoft.Json.Linq.JObject) रिटर्न है ((Newtonsoft.Json.Linq.JObject) obj) .ContainsKey (नाम);" उपरोक्त फ़ंक्शन के रूप में rr789 द्वारा सुझाव दिया गया है। तो कृपया इसे शामिल करने के लिए अपने उत्तर को भी संपादित करें।
बृजेश कुमार त्रिपाठी

1
धन्यवाद @BrijeshKumarTripathi! यह वास्तव में मेरा परिदृश्य था।
र्यानबजेक्सन

4

यह मेरे लिए काम कर रहा है-

  public static bool IsPropertyExist(dynamic dynamicObj, string property)
       {
           try
           {
               var value=dynamicObj[property].Value;
               return true;
           }
           catch (RuntimeBinderException)
           {

               return false;
           }

       }

14
अपवादों को घटित करना और फिर उन्हें पकड़ना एक पसंदीदा समाधान नहीं है क्योंकि फेंकने और पकड़ने के साथ बहुत सारे उपरि जुड़े होते हैं। यह केवल एक अंतिम उपाय है। अपवाद उन परिस्थितियों के लिए डिज़ाइन किए गए हैं जो निष्पादन के दौरान नहीं होना चाहिए जैसे कि नेटवर्क अनुपलब्ध होना। यहां बहुत बेहतर समाधान हैं।
जो भी आदमी

के साथ विफल हो RuntimeBinderExceptionऔर dynamicObj[property].Value जब मूल्य वास्तव में नहीं है ... var value = dynamicObj[property]के लिए पर्याप्त है ... और जब यह मौजूद नहीं है KeyNotFoundException पर Dictionaryफेंक दिया जाता है ... नीचे देखें ...
Matas Vaitkevicius

व्यावसायिक तर्क में अपवादों का उपयोग करना स्वीकार्य समाधान नहीं है। 1 ग्रेड, दूसरा कार्यकाल।
आर्टेम जी

3

समाधान में से कोई भी के लिए काम किया इसके बाद के संस्करण dynamicहै कि आता है से Json, मैं तथापि के साथ एक को बदलने में कामयाब रहे Try catchफेंक दिया (अपवाद प्रकार बदलकर (@ user3359453 द्वारा) KeyNotFoundExceptionके बजाय RuntimeBinderExceptionकुछ है कि वास्तव में काम करता है में) ...

public static bool HasProperty(dynamic obj, string name)
    {
        try
        {
            var value = obj[name];
            return true;
        }
        catch (KeyNotFoundException)
        {
            return false;
        }
    }

यहां छवि विवरण दर्ज करें

आशा है कि यह आपको कुछ समय बचाता है।


1
ऐसी चीजों के लिए अपवादों का उपयोग करने की अनुशंसा नहीं की जाती है। जॉयजेक्ट के लिए कास्टिंग करने और उपयोग करने जैसी किसी चीज़ के लिए जाना चाहिए था ।Property ()! =
Null

3

Serj-TM और user3359453 से उत्तरों को मर्ज करना और ठीक करना ताकि यह ExpandoObject और DynamicJsonObject दोनों के साथ काम करे। यह मेरे लिए काम करता है।

public static bool HasPropertyExist(dynamic settings, string name)
{
    if (settings is System.Dynamic.ExpandoObject)
        return ((IDictionary<string, object>)settings).ContainsKey(name);

    if (settings is System.Web.Helpers.DynamicJsonObject)
    try
    {
        return settings[name] != null;
    }
    catch (KeyNotFoundException)
    {
        return false;
    }


    return settings.GetType().GetProperty(name) != null;
}

2

प्रतिबिंब का उपयोग करना, यह वह फ़ंक्शन है जिसका मैं उपयोग करता हूं:

public static bool doesPropertyExist(dynamic obj, string property)
{
    return ((Type)obj.GetType()).GetProperties().Where(p => p.Name.Equals(property)).Any();
}

फिर..

if (doesPropertyExist(myDynamicObject, "myProperty")){
    // ...
}

2
GetProperties () डायनामिकऑब्जेक्ट पर डायनामिक मेंबर को सूचीबद्ध नहीं करती है। उसके लिए एक समर्पित फ़ंक्शन GetDynamicMemberNames () है।
मार्को गाइगार्ड

Whereपहले लैम्ब्डा अभिव्यक्ति का उपयोग करना , और फिर Anyनिरर्थक है, जैसा कि आप अपनी फ़िल्टरिंग अभिव्यक्ति Anyको भी बना सकते हैं।
फोलपर

1

यदि किसी को जसन से आने वाली एक गतिशील वस्तु को संभालने की आवश्यकता होती है, तो मैंने न्यूटनसॉफ्ट से गतिशील गतिशील वस्तु को संभालने के लिए सेठ रेनो उत्तर को संशोधित किया है। Json.JObjcet।

public static bool PropertyExists(dynamic obj, string name)
    {
        if (obj == null) return false;
        if (obj is ExpandoObject)
            return ((IDictionary<string, object>)obj).ContainsKey(name);
        if (obj is IDictionary<string, object> dict1)
            return dict1.ContainsKey(name);
        if (obj is IDictionary<string, JToken> dict2)
            return dict2.ContainsKey(name);
        return obj.GetType().GetProperty(name) != null;
    }

0

@ कुरूरो से उत्तर का विस्तार करने के लिए, यदि आपको परीक्षण करने की आवश्यकता है कि संपत्ति खाली है, तो नीचे काम करना चाहिए।

public static bool PropertyExistsAndIsNotNull(dynamic obj, string name)
{
    if (obj == null) return false;
    if (obj is ExpandoObject)
    {
        if (((IDictionary<string, object>)obj).ContainsKey(name))
            return ((IDictionary<string, object>)obj)[name] != null;
        return false;
    }
    if (obj is IDictionary<string, object> dict1)
    {
        if (dict1.ContainsKey(name))
            return dict1[name] != null;
        return false;
    }
    if (obj is IDictionary<string, JToken> dict2)
    {
        if (dict2.ContainsKey(name))
            return (dict2[name].Type != JTokenType.Null && dict2[name].Type != JTokenType.Undefined);
        return false;
    }
    if (obj.GetType().GetProperty(name) != null)
        return obj.GetType().GetProperty(name).GetValue(obj) != null;
    return false;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.