2013-05-21 7 views
6

मैं कुछ इस तरह है:रिटर्निंग अभिव्यक्ति <> का उपयोग कर विभिन्न वर्ग गुण

public Expression<Func<Message, bool>> FilterData() 
{ 
    switch (this.operatorEnum) 
    { 
     case FilterParameterOperatorEnum.EqualTo: 
      return message => !string.IsNullOrEmpty(message.Body) && 
           message.Body 
            .Equals(this.value, StringComparison.InvariantCultureIgnoreCase); 

     case FilterParameterOperatorEnum.NotEqualTo: 

      return message => !string.IsNullOrEmpty(message.Body) && 
           !message.Body 
            .Equals(this.value, StringComparison.InvariantCultureIgnoreCase); 

     case FilterParameterOperatorEnum.Contains: 

      return message => 
        !string.IsNullOrEmpty(message.Body) && 
        message.Body.IndexOf(this.value, 
            StringComparison.InvariantCultureIgnoreCase) >= 0; 

     case FilterParameterOperatorEnum.DoesNotContain: 
      return message => 
        !string.IsNullOrEmpty(message.Body) && 
        message.Body.IndexOf(this.value, 
            StringComparison.InvariantCultureIgnoreCase) == -1; 


    } 
} 

आप देख सकते हैं इस Message.Body

मैं अब पर किया जाता है क्या पर अन्य स्ट्रिंग गुणों पर एक ही बात करने के लिए Message कक्षा और मैं उस कोड को डुप्लिकेट नहीं करना चाहता हूं।

वहाँ ऐसा करने के लिए संपत्ति किसी भी तरह में पास करके कोई तरीका है?

उत्तर

1

आप पूरी तरह से मैन्युअल रूप से अभिव्यक्ति रचना कोशिश कर सकते हैं, जो आप एक स्ट्रिंग के रूप संपत्ति नाम निर्दिष्ट करने की क्षमता दे देंगे। यह एक पूर्ण समाधान नहीं है और यह untested है, लेकिन यह आप एक प्रारंभिक बिंदु को देखने के लिए मैं क्या मतलब है दे सकते हैं:

var parameter = Expression.Parameter(typeof(Message), "o"); 
var getname = Expression.Property(parameter, "Body"); 

var isnullorempty = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, getname)); 
var compare = Expression.Equal(getname, Expression.Constant("thisvalue")); 

var combined = Expression.And(isnullorempty, compare); 

var lambda = Expression.Lambda(combined, parameter); 

तो तुम एक पैरामीटर के रूप में स्वीकार करने के लिए "द बॉडी" अपने कार्य बदल जाएगा, और फिर डाली करने के लिए अंत में लैम्ब्डा:

expression<func<Message, bool>> 

मैं लैम्ब्डा बनाने बिल्कुल सही हालांकि वाक्य विन्यास को मिल गया है नहीं हो सकता है।

0

बस संदेश के बजाय संपत्ति प्राप्त करने के लिए अपने कार्य बदल जाते हैं।

या मुश्किल तरीके से संपत्ति के नाम के लिए एक और पैरामीटर गुजरती हैं और प्रतिबिंब का उपयोग कर उसका चयन करें।

सिर्फ सभी विकल्प के लिए परिवर्तन की तुलना में एक विकल्प के लिए संपादित करें।

public Func<Message, string, bool> FilterData() 
    { 
     return (message, propName) => 
     { 
      var prop = message.GetType().GetProperty(propName); 

      if(prop != null){ 
       var propValue = (string)prop.GetValue(message,null); 
       return !string.IsNullOrEmpty(propValue) && ...; 
      } 
      return false; 
     }; 

    } 
+0

और क्या FilterData के शरीर कैसा दिखता है? – Jon

+0

यह सही तरीके से करने के लिए, 'प्रोप' 'null' की जांच करने के बाद, आपको यह भी सुनिश्चित करना चाहिए कि 'prop.CanRead'' true' है। –

3

Eclude अभिव्यक्ति है कि एक अलग लैम्ब्डा अभिव्यक्ति में संपत्ति मान प्राप्त करता है:

public Expression<Func<Message, bool>> FilterData(Func<Message, string> retrievePropValueFunc) 

आपके फ़िल्टर एक्सप्रेशन में, आप तो कॉल कर सकते हैं कि नए लैम्ब्डा अभिव्यक्ति (सिर्फ एक उदाहरण के रूप में एक दिखा रहा है):

return message => !string.IsNullOrEmpty(retrievePropValueFunc(message)) 
     && retrievePropValueFunc(message) 
       .Equals(this.value, StringComparison.InvariantCultureIgnoreCase); 

Body संपत्ति जाने के लिए, retrievePropValueFunc पैरामीटर के लिए message => message.Body पास; जैसा कि आप देखते हैं, आप इसे अन्य गुणों के पुनर्प्राप्ति के लिए अलग-अलग लैम्ब्डा अभिव्यक्तियों को पारित करने के लिए संशोधित भी कर सकते हैं।

+0

क्या 'पुनर्प्राप्तिप्रॉपवैल्यूफन' को 'अभिव्यक्ति >' होने की आवश्यकता है? –

+0

मुझे वर्तमान में "LINQ अभिव्यक्ति नोड प्रकार 'Invoke' LINQ से इकाइयों में समर्थित नहीं है।" – Jon

+0

@SteveGreatrex आप पुनर्प्राप्ति कैसे करते हैं PropValueFunc अगर इसकी अभिव्यक्ति – Jon

0

एक बहुत ही त्वरित और गंदी दृष्टिकोण एक enum प्लस कुछ जादू की तरह हो सकता है:

public enum FilterTarget { Body, AnyOtherProp }; 
public Expression<Func<Message, bool>> FilterData(FilterTarget filterTarget) 
{ 
    string toBeFiltered = string.Empty; 

    switch(filterTarget) 
    { 
     case FilterTarget.Body : 
     { toBeFiltered = message.Body; } break; 
     case FilterTarget.AnyOtherProp : 
     { toBeFiltered = message.AnyOtherProp; } break; 
     default: 
     { 
      throw new ArgumentException(
       string.Format("Unsupported property {0}", filterTarget.ToString() 
      ); 
     } 
    } 

    switch (this.operatorEnum) 
    { 
     case FilterParameterOperatorEnum.EqualTo: 
      return message => !string.IsNullOrEmpty(toBeFiltered) && 
           toBeFiltered.Equals(this.value, StringComparison.InvariantCultureIgnoreCase); 

     /* CUT: other cases are similar */ 
    } 
} 

आप कर सकते हैं FilterData विधि भी अधिक फैंसी दे यह एक params FilterTarget[] इस प्रकार प्राप्त कर रहा बहु छानने क्षमताओं को स्वीकार (बंद मेरे सिर के ऊपर, कोड शामिल नहीं है)।

उपयोग:

var aFilterDataResult = FilterData(FilterTarget.Body);  
var anotherFilterDataResult = FilterData(FilterTarget.AnyOtherProp); 
... 
संबंधित मुद्दे