2012-09-14 11 views
30

मैं एक method in C# बनाया methodNameप्रकार 'System.Linq.Expressions.UnaryExpression' की वस्तु कास्ट करने के लिए 'System.Linq.Expressions.MemberExpression' टाइप करने में असमर्थ

public string GetCorrectPropertyName<T>(Expression<Func<T, string>> expression) 
{ 
    return ((MemberExpression)expression.Body).Member.Name; // Failure Point 
} 

हो और

के रूप में यह बुला लिए
string lcl_name = false; 
public string Name 
{ 
get { return lcl_name ; } 
set 
    { 
     lcl_name = value; 
     OnPropertyChanged(GetCorrectPropertyName<ThisClassName>(x => x.Name)); 
} 
} 

यह ठीक काम करता है अगर संपत्ति स्ट्रिंग है और अन्य सभी प्रकार के लिए इस अपवाद देता है:

की वस्तु कास्ट करने में असमर्थ 'System.Linq.Expressions.MemberExpression' टाइप करने के लिए 'System.Linq.Expressions.UnaryExpression' टाइप करें।

  1. मैं विधि हस्ताक्षर में आपत्ति उठाने का स्ट्रिंग बदल गया है, लेकिन फिर इसे फिर से विफल रहता है।
  2. मैं x => Convert.ToString(x.PropertyName) करने के लिए x => x.PropertyName से बुला बदल गया है और यह अभी भी

मैं गलत कहाँ हूँ विफल रहता है?

+2

आईएमओ इस बदलाव की बेहतरता का उपयोग करना बेहतर है जहां सहायक 'अभिव्यक्ति > 'लेता है। यह कॉल साइट सिंटैक्स को 'GetCorrectPropertyName (() => this.Name) में बदलता है,' जो मेरे विचार में टाइप करने के लिए बेहतर है (जेनेरिक टाइप पैरामीटर देने की कोई आवश्यकता नहीं है) और पढ़ने के लिए बेहतर ('यह नाम' conveys इरादा बेहद अच्छी तरह से)। – Jon

+0

@ जोन: बडी आपका जवाब जोड़ने के लिए स्वतंत्र महसूस करते हैं। यदि वर्तमान उत्तर से बेहतर है, तो मैं निश्चित रूप से आपके स्वीकार करूँगा। –

+0

मैं ऐसा नहीं करना चाहता क्योंकि यह आपके प्रश्न का इरादा रखेगा। लेकिन आप आसानी से इसके लिए कोड यहां ले सकते हैं [http://compositewpf.codeplex.com/SourceControl/changeset/view/65392#1024364), माइक्रोसॉफ्ट वास्तव में प्रिज्म में यह करता है। – Jon

उत्तर

44

आपको उस सदस्य को निकालने के लिए एक अलग पंक्ति की आवश्यकता है जहां इनपुट अभिव्यक्ति एक यूनरी अभिव्यक्ति है।

बस VB.Net से परिवर्तित, इसलिए थोड़ा दूर हो सकता है - अगर मैं किसी भी नाबालिग तोड़ मरोड़ करने की जरूरत है मुझे पता है:

public string GetCorrectPropertyName<T>(Expression<Func<T, Object>> expression) 
{ 
    if (expression.Body is MemberExpression) { 
     return ((MemberExpression)expression.Body).Member.Name; 
    } 
    else { 
     var op = ((UnaryExpression)expression.Body).Operand; 
     return ((MemberExpression)op).Member.Name; 
    }     
} 

वीबी संस्करण है:

Public Shared Function GetCorrectPropertyName(Of T) _ 
      (ByVal expression As Expression(Of Func(Of T, Object))) As String 
    If TypeOf expression.Body Is MemberExpression Then 
     Return DirectCast(expression.Body, MemberExpression).Member.Name 
    Else 
     Dim op = (CType(expression.Body, UnaryExpression).Operand) 
     Return DirectCast(op, MemberExpression).Member.Name 
    End If 
End Function 

नोट कि इनपुट अभिव्यक्ति स्ट्रिंग को आवश्यक रूप से वापस नहीं करती है - जो आपको स्ट्रिंग्स लौटने वाले गुणों को पढ़ने के लिए बाध्य करती है।

+4

एक आश्चर्य है कि ऐसा कुछ क्यों बीसीएल या एक्सटेंशन में अभी तक शामिल नहीं हुआ है। यह अविश्वसनीय रूप से उपयोगी है। – BoltClock

+0

सिर्फ यह जानना चाहता था कि इसका उपयोग कैसे करें और इसे गुणों और विधियों (VB.Net's Sub's और Function's) के लिए कैसे कॉल करें? –

+0

@ निखिल अग्रवाल: आप एक नया प्रश्न पूछने के लिए सबसे अच्छे हैं, इस पर वापस संदर्भ लें, और अपनी ज़रूरतों को पूरी तरह से समझाएं। –

4

इस सवाल (हाँ मैं ओपी हूँ) पूछ के बाद मैं Jon

से प्रश्न पर टिप्पणी प्राप्त है और मैं इस apparently मुक्केबाजी/unboxing से संबंधित है इस

public string ResolvePropertyName<TEntity>(Expression<Func<TEntity>> expression) 
{ 
try { 
    if (expression == null) { 
     Throw New ArgumentNullException("propertyExpression") 
    } 

    object memberExpression = expression.Body as MemberExpression; 
    if (memberExpression == null) { 
     Throw New ArgumentException("The expression is not a member access expression.", "propertyExpression") 
    } 

    object property = memberExpression.Member as PropertyInfo; 
    if (property == null) { 
     Throw New ArgumentException("The member access expression does not access a property.", "propertyExpression") 
    } 

    object getMethod = property.GetGetMethod(true); 
    if (getMethod.IsStatic) { 
     Throw New ArgumentException("The referenced property is a static property.", "propertyExpression") 
    } 
    return memberExpression.Member.Name; 
} catch (Exception ex) { 
    return string.Empty; 
} 
} 
5

के साथ आया था। लम्बाडा अभिव्यक्तियों को लौटने वाले मूल्य प्रकारों को लौटने की आवश्यकता होती है जिन्हें यूनरीएक्सप्रेस के रूप में दर्शाया जाएगा, जबकि संदर्भ प्रकार वापस करने वाले सदस्य को सदस्य एक्सपेरियंस के रूप में दर्शाया जाएगा।

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

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