Tipo narių išraiška reiškia skirtingas išraiškas („MemberExpression“, „UnaryExpression“)

Aprašymas

Turiu išraišką, nurodančią mano tipo turtą. Bet tai neveikia kiekvienam turto tipui. „Tai nereiškia“ reiškia, kad tai sukelia skirtingų tipų išraiškas. Maniau, kad tai kada nors paskatins valstybes MemberExpression , bet ne.

int ir Guid šis rezultatas yra UnaryExpression ir MemberExpression .

Aš šiek tiek supainioti;)

Kodo pavyzdys

Mano klasė

 public class Person { public string Name { get; set; } public int Age { get; set; } } 

Bandymo kodas

 Person p = new Person { Age = 16, Name = "John" }; Expression<Func<Person, object>> expression1 = x => x.Age; // expression1.Body = UnaryExpression; Expression<Func<Person, object>> expression2 = x => x.Name; // expression2.Body = MemberExpression; 

Klausimas

Kaip aš galiu palyginti dvi išraiškas ir patikrinti, ar jos yra to paties tipo ir to paties turto vidurkiai?

Atnaujinkite, atsakykite ir vykdykite mėginį

Ačiū vartotojui dasblinkenlight , kuris privertė mane patekti į teisingą kelią.

Jis pateikė metodą

 private static MemberExpression GetMemberExpression<T>( Expression<Func<T,object>> exp ) { var member = expr.Body as MemberExpression; var unary = expr.Body as UnaryExpression; return member ?? (unary != null ? unary.Operand as MemberExpression : null); } 

GetMemberExpression metodų rezultatus ir patikrinau, ar žymės GetMemberExpression().Member.Name .

 private static bool IsSameMember<T>(this Expression<Func<T, object>> expr1, Expression<Func<T, object>> expr2) { var result1 = GetMemberExpression(expr1); var result2 = GetMemberExpression(expr2); if (result1 == null || result2 == null) return false; return result1.Member.Name == result2.Member.Name; } 
28
19 окт. nustatė dknaack 19 sp 2012-10-19 16:31 '12 at 4:31 pm 2012-10-19 16:31
@ 2 atsakymai

Taip yra todėl, kad Age yra vertės tipas. Norint priversti išraišką, kuri grąžina reikšmės tipą Func<Person,object> , kompiliatorius turi įterpti Convert(expr, typeof(object)) , UnaryExpression .

Tačiau string ir kitiems orientaciniams tipams nereikia įterpti kvadrato, todėl grąžinama „tiesioginės“ narystės išraiška.

Jei norite patekti į „ MemberExpression viduje „ UnaryExpression , galite gauti jo operandą:

 private static MemberExpression GetMemberExpression<T>( Expression<Func<T,object>> exp ) { var member = exp.Body as MemberExpression; var unary = exp.Body as UnaryExpression; return member ?? (unary != null ? unary.Operand as MemberExpression : null); } 
54
19 окт. atsakymas pateikiamas dasblinkenlight 19 okt. 2012-10-19 16:38 '12 4:38 val. 2012-10-19 16:38

Vietoj lyginimo eilutės „ Member.Name aš siūlau lyginti „ PropertyInfo egzempliorius tiesiogiai, kad būtų išvengta klaidingų teigiamų rezultatų, kai dvi skirtingų klasių savybės turi tą patį pavadinimą.

 public static bool IsSameProperty<TSourceA, TSourceB, TPropertyA, TPropertyB>( Expression<Func<TSourceA, TPropertyA>> expA, Expression<Func<TSourceB, TPropertyB>> expB) { MemberExpression memExpA = expA.Body as MemberExpression; MemberExpression memExpB = expB.Body as MemberExpression; if (memExpA == null || memExpB == null) return false; PropertyInfo propA = memExpA.Member as PropertyInfo; PropertyInfo propB = memExpB.Member as PropertyInfo; if (propA == null || propB == null) return false; return propA.Equals(propB); } 

Jūs galite užtikrinti, kad jūsų lambda išraiška būtų sudaryta kaip MemberExpression , o ne UnaryExpression , tiesiog nurodydama teisingą reikšmės tipą (o ne object ) kaip bendrą TResult tipą „ TResult Expression<Func<T, TResult>> .

 Expression<Func<Person, int>> expression1 = x => x.Age; Expression<Func<Person, int>> expression2 = x => x.Age; Expression<Func<Person, string>> expression3 = x => x.Name; Console.WriteLine(IsSameProperty(expression1, expression2)); // True Console.WriteLine(IsSameProperty(expression1, expression3)); // False 
2
19 окт. Atsakymas duotas Douglas 19 okt. 2012-10-19 17:57 '12, 17:57, 2012-10-19 17:57

Kiti klausimai apie žymes arba Užduoti klausimą