2016-08-04 6 views
0

Für den unteren Indexer sollte es so sein, dass für get {} Benutzer MitarbeiterID oder Vornamen übergeben kann und für Satz {} nur MitarbeiterID übergeben kann. HierKönnen wir die Anzahl der Indexer für den gesetzten Operator in Indexern beschränken?

ist der Code:

public Employee this[int employeeid = 0,string firstname = ""] 
{ 
    get 
    { 
     if (employeeid != 0) 
     { 
      return Employees.FirstOrDefault(emp => emp.No == employeeid); 
     } 
     else 
     { 
      return Employees.FirstOrDefault(emp => emp.FirstName == firstname); 
     } 
    } 
    set 
    { 
     if (employeeid == value.No) 
     { 
      Employees.FirstOrDefault(emp => emp.No == employeeid).FirstName = value.FirstName; 
      Employees.FirstOrDefault(emp => emp.No == employeeid).LastName = value.LastName; 
     } 
     else 
     { 
      ArgumentException argEx = new ArgumentException("Falied to update"); 
      System.Windows.Forms.MessageBox.Show(argEx.Message); 
     } 
    } 
} 

Ich möchte nur wissen, ist es eine Syntax, die die Anzahl und Art der Indexer auf Set-Operationen übergeben werden beschränken. Oder fügen Sie einfach einen neuen Indexer für den Satz hinzu, der offensichtlich funktioniert.

Antwort

3

Fügen Sie einen neuen Indexer hinzu. C# hat Indexer hinzugefügt, um eine Array-artige Syntax mit benutzerdefinierten Semantiken bereitzustellen. Die Semantik, die Ihr Code bietet, ist nicht intuitiv und nicht arrayähnlich.

Zum Beispiel employee[123, "Alex"] und employee[123, "Bart"] die gleichen Employee zurückkehren, weil ID gewinnt, wenn beide ID und ein Name vorhanden ist. Dies wäre eine OK Sache für eine richtig benannte Methode zu tun, zum Beispiel

Employee GetEmployeeByIdOrName(int employeeid = 0,string firstname = "") { 
    ... 
} 

Ein Multiparameter-Indexer wird erwartet, dass die gesamte Kombination von Argumenten als einzigen Schlüssel zu behandeln, die Ihre Implementierung nicht tut.

Zum Beispiel, wenn eine Funktion zwei Parameter hat: int und string. Dann, wenn der Benutzer geben kann int oder string aber nicht beides. Denkst du nicht, wir brauchen eine neue Funktionssyntax, die dies ermöglicht.

Sie können es mit einem Paar von Überlastungen heute das gleiche tun Aufruf der Methode:

// The following two methods are visible to users of your object 
public Employee GetEmployee(int id) { 
    return GetEmployeeByIdOrName(id, null); 
} 
public Employee GetEmployee(string name) { 
    return GetEmployeeByIdOrName(0, name); 
} 
// This private method provides an implementation 
private Employee GetEmployeeByIdOrName(int employeeid, string firstname) { 
    ... 
} 
+3

abgelegt unter „nur weil Sie können, bedeuten doesnt Sie sollten“ – Jamiec

+0

OK Parameter für Satz gemeinsam sein werden und erhalten. Und es gibt nur die Funktionalität der optionalen Parameter und nicht einschränkende Parameter. Zum Beispiel, wenn eine Funktion zwei Parameter int und string hat. Dann, wenn der Benutzer int oder string aber nicht beide geben kann. Denkst du nicht, wir brauchen eine neue Funktionssyntax, die dies ermöglicht. Indexer und Funktionen sind unterschiedlich, aber in Bezug auf Parameter teilweise ähnlich. Also stelle ich diese Frage. –

+1

@NithinB Sie müssen Methode Überladung verwenden, die für Ihren Fall ist, dass optionale Parameter. – user3185569

2

Sie nicht verschiedene Parameter für Setter und Getter in der gleichen Indexer verwenden können.

Um ehrlich zu sein, sehe ich, was Sie versuchen, als völlig unklar für die Entwickler mit Ihrer Klasse zu tun.

Ich würde nicht Indexer verwenden, um Objekte innerhalb eines Arrays innerhalb einer Klasse nach ID oder nach Name in der gleichen Methode zu finden.

Warum Sie nicht nur geteilt als in zwei Verfahren (Indexer) für jede Suchkriterien:

public Employee this[int employeeid] 
{ 
    get 
    { 
     return Employees.FirstOrDefault(emp => emp.No == employeeid); 
    } 
} 

public Employee this[string firstname] 
{ 
    get 
    { 
     return Employees.FirstOrDefault(emp => emp.FirstName == firstname); 
    } 
} 

Ihre Set Indexer völlig unklar und irreführend ist. Sie überprüfen, ob das übergebene Objekt dieselbe ID wie das Objekt hat, für das Sie die Indexermethode aufrufen, und aktualisieren Sie dann diese Werte von den übergebenen. Ganz zu schweigen davon, dass Sie nur zwei Eigenschaften in diesem Objekt aktualisieren. Das ist ein schlechtes Design, während eine Alternative klare Lösung wäre:

public void UpdateEmployee(Employee updatedEmployee) 
{ 
    if (this.No == updatedEmployee?.No) 
    { 
     this.FirstName = updatedEmployee.FirstName; 
     this.LastName = updatedEmployee.LastName; 
    } 
    else 
    { 
     // throw 
    } 
} 
+0

ja ich weiß, es gibt viele Möglichkeiten zu implementieren wie Hinzufügen neuer Indexer oder Funktionen. Aber wir können den Indexer nicht so deklarieren wie public string dies [(set) (get) int x, (get) String y]. Was bedeutet, dass get {} von beiden Parametern aufgerufen werden kann und set {} nur durch den ersten Parameter. Ich denke, diese Art von Syntax wird die Kodierung kleiner und flexibler zu verwenden machen. –

+0

@NithinB Nein, du kannst nicht. Dies ist in der Antwort angegeben, dass Sie die Getter-Parameter nicht von den Parametern des Settors trennen können. – user3185569

+0

@NithinB Durch das Teilen der Indexer wird außerdem deutlich, was Ihre Absicht ist. Was sowieso besser ist. Sie sollten immer Klarheit über ausgefallene Sachen wählen. – user3185569

Verwandte Themen