2017-02-12 1 views
0

Ich versuche herauszufinden, ob es eine Möglichkeit gibt, func (oder eine ähnliche Methode) auf das linke Objekt anzuwenden. Bsp .:C# func <> angewendet auf das Objekt auf der linken Seite

member1.MyFunction() 

Hier ist ein vereinfachtes Kontext der Nutzung. Wir haben ClassA, die eine Liste von ClassB enthält und eine Methode, um die Elemente von ClassB zusammenzufassen. Und Klasse B besitzt zwei Attribute memberX und memberY, die vom doppelten Typ sind. Die Funktion ist zu verwenden, um auszuwählen, welches Mitglied von ClassB wir addieren möchten.

Ich habe einen Fehler in der Zeile, wo ich

theSum += TheList[i].TheFunction(); 

Der Fehler schreiben ist:

CS1061 C# keine Definition für und keine Erweiterung Methode ein erstes Argument enthält die Annahme Typ könnte gefunden werden (fehlt eine Verwendungsrichtlinie oder eine Baugruppenreferenz?)

Kennt jemand eine Problemumgehung? Meine Forschung konnte mich nicht zu etwas führen, das auf die linke Seite der generischen Funktion angewendet wurde.

public class ClassA 
{ 
    public List<ClassB> TheList; 
    public ClassA() 
    { 
     ClassB m1 = new ClassB(1, 2); 
     ClassB m2 = new ClassB(1, 2); 
     ClassB m3 = new ClassB(1, 2); 
     TheList= new List<ClassB>() { m1, m2, m3 }; 
    } 
    private double CalculateSum(Func<double> TheFunction) 
    { 
     double theSum = 0; 
     for (int i = 0; i < TheList.Count(); i++) 
     { 
      theSum += TheList[i].TheFunction(); 
      // I'd like to use the previous line instead of having to write 
      // a function for both of the following. 
      // theSum += TheList[i].GetMember1(); 
      // theSum += TheList[i].GetMember2(); 
     } 
     return theSum; 
    } 
} 
public class ClassB 
{ 
    private double memberX; 
    private double memberY; 
    public ClassB(double x, double y) 
    { 
     memberX = x; 
     memberY = y; 
    } 

    public double GetMember1() { return memberX; } 
    public double GetMember2() { return memberY; } 
} 

Antwort

1

Sie könnten so etwas wie dies versuchen.

public static class ClassBExtensions 
{ 
    public static double Sum(this ClassB arg, Func<ClassB, double> func) 
    { 
     return func(arg); 
    } 
} 

es dann so

Func<ClassB, double> func = null; // define your func here 
for (int i = 0; i < aList.Count(); i++) 
    { 
     theSum += aList[i].Sum(func); 
    } 
return theSum; 
+0

Ich versuchte das zu vermeiden, aber da ich die Antworten (und die Suchergebnisse) sehe, glaube ich, dass es keine andere Möglichkeit gibt, Func <> oder andere ähnliche Methoden zu verwenden. –

+0

Siehe mein Update, wenn Sie die Funktion auf das Objekt auf der linken Seite anwenden möchten. –

3

gut nicht mit ganz so Syntax, aber man kann einfach nutzen:

theSum += aFunction(aList[i]); 

Ich nehme an, Sie könnte eine Erweiterungsmethode für diese schreiben, aber die oben ist mehr idiomatische.

In der Tat, mit LINQ zu beginnen wäre idiomatische - Ihr calculateSum Verfahren ist bereits in LINQ als Sum, so dass man nennen könnte:

double sum = aList.Sum(x => x.getMember1()); 

Natürlich mehr idiomatisch, würden Sie Eigenschaften verwenden anstelle von Methoden:

double sum = aList.Sum(x => Member1); 

auch für das Idiom, dann würden Sie sicherstellen, dass alle Methoden, die Sie tun folgen .NET-Namenskonventionen haben, mit einem Großbuchstaben beginnen. I stark rät Ihnen, die Namenskonventionen (auch für Wegwerf-Demo-Code) sofort zu folgen.

private double calculateSum(Func<ClassB, double> aFunction) 
{ 
    double theSum = 0; 
    for (int i = 0; i < aList.Count(); i++) 
    { 
     theSum += aFunction(aList[i]); 
    } 

    return theSum; 
} 

aktualisieren

Wenn Sie wirklich anwenden möchten die func auf das Objekt zu ihrer Linken, dann könnten Sie eine Erweiterungsmethode definieren:

+0

ich diese Antwort wirklich das Gefühl, sollte die neue Definition von 'aFunction' für die erste Zeile enthalten. Mit einem 'Func ' wird dies nichts anderes tun, als dem OP einen anderen Fehler zu geben. – Chris

+0

Ich habe meinen Beitrag bearbeitet, um näher an die Namenskonventionen zu kommen. Danke für Ihre Hilfe. –

0

nennen Wenn ich Sie richtig verstehe, Sie eine Methode „auf“ ClassB wollen, dass einer ihrer Werte zurückgibt.(Ob ClassB sollte ein solches Verfahren haben oder nicht - es ist einfach ein Teil der Berechnung sein könnte und als solche tatsächlich zu ClassA Zugehörigkeit - ist eine andere Frage.)

Wenn Sie ClassB ändern können, einfach dort hinzu:

public class ClassB 
{ 
    private double memberX; 
    private double memberY; 
    public ClassB(double x, double y) 
    { 
     memberX = x; 
     memberY = y; 
    } 

    public double GetMember1() { return memberX; } 
    public double GetMember2() { return memberY; } 

    public double AFunction() 
    { 
     bool condition = ... 
     return condition ? memberX : memberY; 
    } 
} 

ich bin mit dem ternären Operator ?: hier einige Räume auf if/else zu speichern.

Nun, wenn Sie können nicht Änderung ClassB, extension methods (wie in der CS1061 Fehlermeldung angedeutet) könnten Ihnen helfen:

public static class ClassBExtensions 
{ 
    public double AFunction(this ClassB b) 
    { 
     bool condition = ... 
     return condition ? b.GetMember1() : b.GetMember2(); 
    } 
} 

können Sie jetzt einfach .AFunction() auf jeder Instanz vom Typ nennen ClassB, als ob die Methode wurde ursprünglich dort deklariert. Beachten Sie, dass Erweiterungsmethoden nur auf öffentlich zugängliche Felder zugreifen können.

Sie könnten auch in properties aussehen wollen die es erlauben, Ihre ClassB Definition zu reduzieren:

public class ClassB 
{ 
    public ClassB(double x, double y) 
    { 
     MemberX = x; 
     MemberY = y; 
    } 

    public double Member1 { get; } 
    public double Member2 { get; } 

    /* 
    public double AFunction() 
    { 
     bool condition = ... 
     return condition ? Member1 : Member2; 
    } 
    */ 
} 
+0

Ich werde definitiv meine Klassendefinition wie vorgeschlagen reduzieren. Ich war mir der Existenz von Erweiterungsmethoden nicht bewusst, es ist eine gute Lektüre. AsI kann Klasse B ändern, Ihr Vorschlag könnte für mich gut sein, aber ich muss noch sehen, ob es für meine nicht vereinfachte Anwendung am besten ist. –

Verwandte Themen