2009-03-23 11 views
39

क्या यह पता लगाना संभव है कि दो अभिव्यक्ति समान हैं या नहीं?दो अभिव्यक्तियों को कैसे जांचें <Func <T, bool>> वही

की तरह दिए गए निम्न चार भाव:

 Expression<Func<int, bool>> a = x => false; 
     Expression<Func<int, bool>> b = x => false; 
     Expression<Func<int, bool>> c = x => true; 
     Expression<Func<int, bool>> d = x => x == 5; 

तो, कम से कम हम कि देख सकते हैं:

  • a == b
  • a != c
  • a != d

लेकिन क्या मैं इसे अपने कोड में ढूंढने के लिए कुछ भी कर सकता हूं? तय करता है कि निर्दिष्ट ऑब्जेक्ट वर्तमान Object के बराबर है:

MSDN लाइब्रेरी, जहां यह कहना है कि

Equals में झांकना लिया। (Object से विरासत।)

जो मुझे लगता है कि इसका मतलब है कि कम से कम अभिव्यक्ति वर्ग overrided नहीं किया है Equatable बनने के लिए बराबर विधि? तो आप यह कैसे करेंगे? या मैं यहाँ बहुत ज्यादा पूछ रहा हूँ? : पी

+0

यदि वहां 'सदस्यइन्फो' शामिल है, तो मेरा मतलब है कि कुछ विधि, क्षेत्र की संपत्ति, तो आप पहले सदस्यइंफो प्राप्त कर सकते हैं, और इसके हैश की गणना कर सकते हैं – nawfal

उत्तर

32

आप टाइप कर सकते हैं जिसका उपयोग Linq to db4o के अंदर किया जाता है। यह इंटरफेस IEqualityComparer < टी > लागू करता है, इसलिए यह सामान्य संग्रह के साथ-साथ एक स्टैंडअलोन उपयोग के लिए उपयोग करने योग्य है।

यह अभिव्यक्ति से हैशकोड की गणना करने के लिए समानता के लिए दो अभिव्यक्तियों की तुलना करने के लिए ExpressionComparison प्रकार और HashCodeCalculation का उपयोग करता है।

इसमें सभी अभिव्यक्ति वृक्ष का दौरा करना शामिल है, इसलिए यदि आप इसे बार-बार करते हैं तो यह बहुत महंगा हो सकता है, लेकिन यह भी काफी आसान हो सकता है।

कोड जीपीएल या dOCL

उदाहरण के लिए के तहत उपलब्ध है, यहाँ अपने परीक्षण है:

using System; 
using System.Linq.Expressions; 

using Db4objects.Db4o.Linq.Expressions; 

class Test { 

    static void Main() 
    { 
     Expression<Func<int, bool>> a = x => false; 
     Expression<Func<int, bool>> b = x => false; 
     Expression<Func<int, bool>> c = x => true; 
     Expression<Func<int, bool>> d = x => x == 5; 

     Func<Expression, Expression, bool> eq = 
      ExpressionEqualityComparer.Instance.Equals; 

     Console.WriteLine (eq (a, b)); 
     Console.WriteLine (eq (a, c)); 
     Console.WriteLine (eq (a, d)); 
    } 
} 

और यह वास्तव में सच है, झूठी, गलत प्रिंट करता है।

+0

आशाजनक लग रहा था, लेकिन ये अभिव्यक्ति कॉम्परिसन (ए, बी) क्या हैं .अरेक्वाल और हैशकोड गणना (अभिव्यक्ति) .शकोड? – Svish

+1

आप कार्यान्वयन ब्राउज़ कर सकते हैं, वे एक ही फ़ोल्डर में हैं। –

+0

मुझे लगता है कि मैं जो कुछ भी पता लगाने की कोशिश कर रहा हूं उसे हल करने के लिए मैं बस एक और तरीका ढूंढने की कोशिश करूंगा: पी लेकिन आपका उत्तर एक कामकाजी समाधान प्रदान करता है, इसलिए मैं इसे स्वीकृत के रूप में चिह्नित करूंगा =) – Svish

4

यह मुझे मारता है कि मामलों के सबसे सरल को छोड़कर यह करना मुश्किल हो सकता है।

उदाहरण के लिए:

var numbers1 = Enumerable.Range(1, 20); 
Expression<Func<int, IEnumerable<int>>> a = x => numbers1; 
var numbers2 = Enumerable.Range(1, 20); 
Expression<Func<int, IEnumerable<int>>> b = x => numbers2; 

तकनीकी तौर पर, इन समान हैं, लेकिन यह कैसे IEnuemrable के मूल्यांकन के बिना निर्धारित किया जा सकता है प्रत्येक अभिव्यक्ति में लौट आए?

+1

मैं आपको यहां लोगों से पूछ रहा हूं: पी हेहे। लेकिन हाँ, मैं समस्या देख सकता हूं .. लेकिन मैं भी इसे देख सकता हूं .. इसे नहीं देख सकता। जैसा आपने कहा था, तकनीकी रूप से वे वास्तव में बराबर हैं। और, कम से कम, मुझे लगता है कि एक अभिव्यक्ति वृक्ष अपने नोड्स और डेटा प्रकारों के आधार पर एक और अभिव्यक्ति वृक्ष के साथ तुलनीय होना चाहिए। – Svish

+4

आपके उदाहरण में मुझे लगता है कि मैंने उन अभिव्यक्तियों को असमान माना होगा, क्योंकि उनमें एक वस्तु का संदर्भ शामिल है जो समान नहीं हैं ... – Svish

+0

संख्या 1 या संख्या 2 को कॉन्स्टेंटएक्सप्रेस नोड के रूप में क्रमबद्ध किया जाएगा, जिनके मान समान नहीं होंगे । –

11

आलसी उत्तर के रूप में, आप ToString() देख सकते हैं - कम से कम यह इंगित करना चाहिए कि वे स्पष्ट रूप से अलग कहां हैं (हालांकि इसमें वहां var-name शामिल होगा, इसलिए यह वही होना चाहिए)।

समकक्ष सटीक जांचने के लिए ... बहुत कठिन - बहुत सारे काम, कई नोड प्रकारों पर।

+0

लॉल, अब वास्तव में काम का प्रकार हो सकता है ...: डी – Svish

+2

नहीं, प्रत्येक अभिव्यक्ति में यूएसबी नहीं है ले स्ट्रिंग प्रतिनिधित्व। उदाहरण के लिए कनवर्ट यह इंगित नहीं करता कि यह किस प्रकार से परिवर्तित होता है। –

+2

बिल्कुल - मैंने कहा कि यह स्पष्ट रूप से गलत जवाब मिलेगा, लेकिन यह इसके बारे में है। पूरी तरह से काम करने के लिए आपको पेड़ को सही ढंग से चलने, वास्तविक ऑपरेटरों का उपयोग करने, आदि की जांच करने की आवश्यकता होगी। –

संबंधित मुद्दे