2014-12-18 6 views
5

Ich versuche, eine Hilfsfunktion (für eine Klasse) zu erstellen, die 2 Objekte akzeptiert und vergleicht eine Eigenschaft für beide KlassenSo erstellen Sie eine Methode, die 2 Objekte des gleichen Typs, eine Eigenschaft akzeptiert und vergleicht die Werte

Diese Eigenschaften sind immer nur einfache Typen wie string, int und bool

Nutzungs

Compare(widget1,widget2,x => x.Name) 

Was ich bisher

private void CompareValue<T>(Order target, Order source, Func<Order, T> selector) 
    { 
    if(target.selector != source.selector) 
    { 
     // do some stuff here 
    } 
    } 

Offensichtlich oberhalb der Code nicht funktioniert

Jede Hilfe würde geschätzt, dank

Antwort

10

Sie können eine Einschränkung IEquatable<T> hinzufügen:

private void CompareValue<T>(Order target, Order source, Func<Order, T> selector) 
    where T : IEquatable<T> 
{ 
    if (!selector(target).Equals(selector(source)) 
    { 
     // ... Do your stuff 
    } 
} 

Dies würde die angegebenen Typen (wie auch viele andere) behandeln und es dem Compiler ermöglichen, Sie vor Anwendungsfällen zu schützen, in denen dies wahrscheinlich ist unangemessen sein.

Beachten Sie, dass Sie auch den Func<T,U>, dh: selector(target) und selector(source) aufrufen müssen, um den resultierenden Wert zu erstellen.

+0

Ich hatte gehofft, für einen kühlen 'nameof' Trick, der erlauben würde, den Lambda-Ausdruck zu eliminieren. Kein solches Glück. – zmbq

1

Wenn Sie eine völlig generische Version wollte:

public void CompareValue<TModel,TProperty>(TModel x, TModel y, Expression<Func<TModel, TProperty>> expression) 
    where TModel : class 
    where TProperty : IEquatable<TProperty> 
{ 
    MemberExpression memberExpression = expression.Body as MemberExpression; 
    Type modelType = typeof(TModel); 
    PropertyInfo propInfo = modelType.GetProperty(memberExpression.Member.Name); 

    TProperty xValue = (TProperty)propInfo.GetValue(x); 
    TProperty yValue = (TProperty)propInfo.GetValue(y); 
    if (xValue.Equals(yValue)) 
    { 
     Console.WriteLine("Match!"); 
    } 
} 

Verbrauch:

CompareValue(widget1, widget2, x => x.Name); 
+0

scheint nicht für Zeichenfolge zu arbeiten, memberExpression ist null .. Bin ich es falsch verwenden? (Beispiel https://dotnetfiddle.net/5JDkAR) – Default

+1

korrekt, dies scheint zu funktionieren, wenn TModel ein Objekt ist und der Ausdruck eine Eigenschaft anvisiert, aber meine Fähigkeiten sind nicht so, um herauszufinden, warum –

+0

@Default: Den Zweck besiegen des Ausdrucks, wenn du gerade gerade Objekte vergleichst, bist du nicht? Wenn Sie "x" gegen "y" gerade vergleichen wollen, brauchen Sie wahrscheinlich nur einen 'CompareValue (T x, T y) wobei T: IEquatable ' Methodensignatur. Der Ausdruck dient dazu, Eigenschaften zu referenzieren. –

Verwandte Themen