Die 4 von C#.net bereitgestellten Schlüsselwörter in, out, ref und paras werden häufig in der Entwicklung verwendet. Was ist also der Unterschied?
in wird nur in Delegaten und Schnittstellen verwendet;
Beispiel:
//测试模型 class Model { public int a { get; set; } public Model(int a) { this.a = a; } }//创建3个实例List<Model> modelList= new List<Model>() { new Model(1), new Model(4), new Model(6) };//调用foreach接口,试着操作3个实例,赋值为nullmodelList.ForEach(e=>e=null); //查看结果://modelList的取值不变。
Bei der Analyse des Grundes ist der Parameter von ForEach die Delegatfunktion:
//ForEach方法:public void ForEach(Action<T> action);//委托声明:public delegate void Action<in T>(T obj);
Der Delegat ist generisch und dem Typ T geht das Schlüsselwort in voran. Aufgrund des Schlüsselworts in kann T obj nicht geändert werden.
Probieren Sie den Test aus:
//修改元素e的属性amodelList.ForEach(e=>{e.a*=2;});
Als Ergebnis wird jedes Element mit 2 multipliziert und ergibt 2,8,12. Es ist ersichtlich, dass die Eigenschaften des Objekts geändert werden können.
Hinweise zur Verwendung des Schlüsselworts out:
1) Bei formalen Parametern ohne out muss beim Definieren einer Funktion einer der Funktion vor der Rückgabe zugewiesen werden Wert.
2) Beim Aufruf einer Funktion muss Parametern ohne out kein Anfangswert zugewiesen werden.
3) Der Wert des formalen Parameters out wird als Referenz (als Referenz) übergeben
out-Verwendungsszenario:
Wenn eine Funktion mehrere Werte zurückgibt, wird out normalerweise verwendet, um einen davon zurückzugeben
public bool Operation(out Model updateMod) { updateMode = new Model(5); try{ // my operation ... // return true; } catch{ //写入日志 return false; } }//使用Model um; //未初始化bool rtnMsg = Operation(out um); //如果初始化,传值通过reference//分析://返回um,如果rntMsg为ture,则um按照预想逻辑被赋值, //如果rntMsg为false 则um未按照预想逻辑被赋值。
In C#.net gibt es eine Art TryParse-Funktion, die eine weitere wichtige Anwendung von out darstellt. Wenn Sie interessiert sind, lesen Sie bitte: Durch Parse und TryParse: Try-Parse- und Tester-Doer-Modi
ref-Schlüsselwort wird verwendet, um die Parameterübergabe zu ändern, Änderung nach Wert durch Referenz. Der ursprüngliche Wert wird mit oder ohne Referenz übergeben.
Zum Beispiel:
public void reviseModel(int a) { a = 12; } Model model = new Model(10); //调用reviseModelreviseModel(model.a); //model.a仍然=10;by-valuereviseMode(ref model.a); //编译不过,提示ref后的参数不归类与变量int a; reviseMode(ref a); //如果不给变量a赋一个初始值, //编译器也是提示:调用前未被赋值的错误 //因此赋值int a= model.a; //变量a初始值为10;reviseMode(ref a); //修改变量a=12;但是model.a的值仍然为10
Wie ändere ich das Attribut a im Objektmodell, um es in 12 zu ändern?
//直接将参数设为Model对象,则函数调用时,传值通过by referencepublic void reviseModel(Model md) { md.a = 12; } reviseModel(model );//传值通过by reference
Daher eine Zusammenfassung der Verwendung des Schlüsselworts ref:
ref wird zur Verarbeitung von Wertvariablen wie Grundtypen, Strukturen usw. verwendet. Sie müssen nicht neu sein und Die Wertübertragung basiert auf einer Wertkopie.
1) Die Variable nach ref, wenn es sich um einen Werttyp handelt, wird nach dem Hinzufügen von ref zu einem als Referenz übergebenen Wert.
2) Die Variable nach ref, wenn es sich um eine Referenz handelt Typ (Referenztyp), dann gibt es keinen Unterschied zwischen dem Hinzufügen von ref oder nicht;
3) Der Variablen nach ref muss vor der Verwendung ein Wert zugewiesen werden
4) Der Variablen nach ref kann kein Wert zugewiesen werden eine Referenz Typattribute
Das Obige ist die grundlegende Analyse, die für die Verwendung ausreichend ist. Wenn Sie dieses Problem eingehender analysieren möchten, fahren Sie bitte fort.
4 Ausführliche Diskussion der Out-Refs
Analysieren Sie hauptsächlich die Verwendung von Out-Refs und welche Auswirkungen sie haben, wenn sie nicht verwendet werden.
1) In C# gibt es eine Methodenklasse namens Try..., wie z. B. Int.TryParse. Sie gibt einen Bool-Wert zurück und versucht, eine Zeichenfolge zu analysieren gibt true zurück und die resultierende Ganzzahl ist. Das int wird als zweites Out übergeben.
Siehe den Analyseartikel
Richtlinien zum Ausnahmedesign
Durch Parse und TryParse: Try-Parse- und Tester-Doer-Modi
Wie aus dem Artikel hervorgeht, im Vergleich zur Untermethode Parse ohne Out-Parameter , wenn beim Parsen die Zeichenfolge fehlschlägt, wird eine Parameterfehlerausnahme ausgelöst.
Mit der Try...-Methode geschriebener Code ist prägnanter als der mit der Try...catch-Methode geschriebene Code, daher ist dies zu einem häufigen Szenario für die Verwendung von Out-Parametern geworden.
2) Vergleich zwischen Java und C#
In Java, HashMap
// HashMap<K, V> map; // K key; V val = map.get(key);if (val != null) { // ...}
aber val == null, es kann sein, dass es keinen Schlüssel für diesen Schlüssel gibt Die Karte ist möglicherweise bereits vorhanden, ihr Wert ist jedoch null.
Um zwischen den beiden zu unterscheiden, stellt HashMap die Methode „containsKey()“ bereit. Die korrekte Schreibweise lautet also so:
// HashMap<K, V> map; // K key;if (map.containsKey(key)) { V val = map.get(key); // ...}
Die internen Operationen von containsKey() und get() sind fast genau gleich. Sie müssen beide eine Hash-Suche durchführen, aber sie geben einfach zurück verschiedene Teile der Suchergebnisse. Mit anderen Worten: Wenn Sie es gemäß dieser „richtigen Schreibmethode“ schreiben, verursacht der einmalige Zugriff auf HashMap doppelte Kosten. Tassen!
C# hat viele solcher detaillierten Designs, die rücksichtsvoller sind als Java. Sehen Sie, wie C# das Schlüsselwort out verwendet, um dieses Problem zu beheben.
System.Collections.Generic.Dictionary
TryGetValue: Dictionary(TKey, TValue).TryGetValue Method (TKey, TValue) (System.Collections.Generic)public bool TryGetValue( TKey key, out TValue value )ParameterskeyType: TKey The key of the value to get. valueType: TValue
Mit dieser Methode kann die C#-Version, die dem obigen Java-Code entspricht, wie folgt geschrieben werden:
// Dictionary<TKey, TValue> dict; // TKey key; TValue val;if (dict.TryGetValue(key, out val)) { // ...}
Dies ist Die Semantik von ContainsKey und Item[Key] wird kombiniert, um alle Informationen, die in einer Hash-Suche gefunden werden können, auf einmal zurückzugeben, wodurch der redundante Vorgang von „zwei Suchvorgängen“ aus der Quelle vermieden wird, was sich positiv auf die Leistung auswirkt Programm.
C#.net stellt ein Schlüsselwort params bereit. Nachdem ein Kollege einmal mehrere Versionen meiner überladenen Funktionen gesehen hatte, sagte er ruhig zu mir: „Ja, du kannst params verwenden.“ Ich habe es später überprüft und bin jetzt daran gewöhnt. Ich habe einfach alle vorherigen Versionen entfernt und es mithilfe von Parametern umgestaltet.
Anschließend werde ich über die Verwendung von Params und den Prozess sprechen, den ich durchlaufen habe.
5.1 Anforderungen des Problems
Auf der Clientseite ändern Kunden häufig die Abfragefelder. Vor ein paar Tagen gingen sie zum Server, um mehrere Modelle basierend auf 4 Schlüsselfeldern abzufragen um ein weiteres Abfragefeld hinzuzufügen.
Abfragemethode basierend auf 4 Schlüsselfeldern:
public void GetPlansByInputControl(string planState, string contactno,DatePair dp) { string planStat = ""; switch (planState) { case "...": planStat = "..."; break; case "...": planStat = "..."; break; } plans = getPlansWithCondition(Convert.ToDateTime(dp.startValue), Convert.ToDateTime(dp.endValue), planStat, contactno); }
Die aufgerufene getPlansWithCondition-Methode ist
private List<MPartPlan> getMPartPlansWithCondition(DateTime dateTime, DateTime dateEndTime, string planStat, string contactNo) { var conditions = new CslSqlBaseSingleTable(); conditions.AddCondition("RequireStartDate", dateTime, DataCompareType.GreaterOrEqual); conditions.AddCondition("RequireStartDate", dateEndTime, DataCompareType.LessOrEqual); conditions.AddCondition("OrderCode", contactNo, DataCompareType.Equal); if (!string.IsNullOrEmpty(planStat)) { conditions.AddCondition("PlanState", planStat, DataCompareType.Equal); } return _cslMPartPlan.QueryListInSingleTable(typeof(MPartPlan), conditions); } }
Das Problem tritt auf, wenn dem Abfragefeld ein weiteres hinzugefügt wird. Lädst du noch eine Version neu?
5.2 Anwenden von Parametern
private List<MPartPlan> getMPartPlansWithCondition(DateTime dateTime, DateTime dateEndTime, string planStat, string contactNo,string newField);
Wenn C# Parameter bereitstellt, ist es natürlich nicht erforderlich, getMPartPlansWithCondition wie folgt direkt umzuschreiben
private List<MPartPlan> getMPartPlansWithCondition(params object[] queryConditions); { queryConditions[0] queryConditions[1] queryConditions[2] queryConditions[3] queryConditions[4] //放到字典中dict sqlQuery(dict); }
Fügen Sie Abfragefelder nach Ihren Wünschen hinzu In Zukunft, solange Sie diese Funktion einfach ändern, müssen Sie die überladene Version nicht hinzufügen oder löschen! ! !
Kundenanruf, einfach ein Feld direkt hinzufügen
_bsl.GetPlansByInputControl(field1, field2,field3,field4,field5);
5.3 Zusammenfassung
queryFun(params object[] objs), eine Funktion mit diesem Parameter erfordert nur eine Version, wodurch das Problem mehrerer überlasteter Versionen aufgrund inkonsistenter Zahlen gelöst wird.
Beim Aufruf durch den Client können die Attributparameter aufgelistet werden eins nach dem anderen.
Die 4 von C#.net bereitgestellten Schlüsselwörter in, out, ref und paras werden häufig in der Entwicklung verwendet. Wie werden sie verwendet?
Was ist der Unterschied zu C#? Eine detaillierte Einführung in die Verwendung von in, out, ref, paras. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!