Heim > Backend-Entwicklung > C#.Net-Tutorial > Detaillierte Erläuterung optionaler Parameter und Beispiele benannter Parameter

Detaillierte Erläuterung optionaler Parameter und Beispiele benannter Parameter

零下一度
Freigeben: 2017-06-24 09:46:31
Original
2491 Leute haben es durchsucht

9.1 Optionale Parameter und benannte Parameter

    class Program
    {
        private static int s_n = 0;

        private static void M(int x = 9, string s = "A", DateTime dt = default(DateTime), Guid guid = new Guid())
        {
            Console.WriteLine("x={0},s={1},dt={2},guid={3}", x, s, dt, guid);
        }
        public static void Main()
        {
            //1.等同于M(9,"A",default(DateTime),new Guid());
            M();

            //2.等同于M(8,"X",default(DateTime),new Guid());
            M(8, "X");

            //3.等同于M(5,"A",DateTime.Now,Guid.NewGuid());
            M(5, guid: Guid.NewGuid(), dt: DateTime.Now);

            //4.等同于M(0,"1",default(DateTime),new Guid());
            M(s_n++, s_n++.ToString());

            //5.等同于以下两行代码:
            //string t1="2";int t2=3;
            //M(t2,t1,default(DateTime),new Guid());
            M(s: (s_n++).ToString(), x: s_n++);
        }
    }
Nach dem Login kopieren

9.1.1 Regeln und Prinzipien

  • können Methoden, Konstruktormethoden und parametrisierte Eigenschaften (C#-Indexer) Parameter sein Geben Sie Standardwerte an. Sie können auch Standardwerte für Parameter angeben, die Teil der Delegatendefinition sind.

  • Parameter mit Standardwerten müssen nach allen Parametern ohne Standardwerte platziert werden. Es gibt jedoch eine Ausnahme: Parameter wie „Parameter-Array“ müssen nach allen Parametern (einschließlich denen mit Standardwerten) platziert werden, und das Array selbst darf keinen Standardwert haben.

  • Der Standardwert muss ein konstanter Wert sein, der zur Kompilierungszeit bestimmt werden kann (einschließlich primitiver Typen, Aufzählungstypen und aller Referenztypen, die auf Null gesetzt werden können). Ein Parameter eines Werttyps legt den Standardwert auf eine Instanz des Werttyps fest und bewirkt, dass alle seine Felder Nullwerte enthalten. Sie können die Schlüsselwörter default oder new verwenden, um diese Bedeutung auszudrücken. Der von den beiden Syntaxen generierte IL-Code ist genau derselbe.

  • Parametervariablen nicht umbenennen, da sonst jeder Aufrufer, der tatsächliche Parameter anhand des Parameternamens übergibt, auch seinen Code ändern muss.

  • Das Ändern des Standardwerts eines Parameters ist potenziell gefährlich , wenn die Methode von außerhalb des Moduls aufgerufen wird. Die Anrufstelle (wo der Anruf getätigt wird) bettet Standardwerte in ihre Anrufe ein. Wenn Sie später den Standardwert des Parameters ändern, aber den Code mit der Aufrufstelle nicht neu kompilieren, wird beim Aufruf Ihrer Methode der alte Standardwert übergeben. Erwägen Sie die Verwendung des Standardwerts 0/null als Sentinel-Wert , um das Standardverhalten anzuzeigen. Beispiel:

        //不要这样做:
        private static string MakePath(string filename = "Untitled")
        {
            return string.Format(@"c\{0}.txt", filename);
        }
    
        //而要这样做:
        private static string MakePath(string filename = null)
        {
            return string.Format(@"C:\{0}.txt", filename ?? "Untitled");
        }
    Nach dem Login kopieren
  • Wenn der Parameter mit dem Schlüsselwort ref oder out markiert ist, kann der Standardwert nicht festgelegt werden.

Beachten Sie beim Aufruf einer Methode mit optionalen oder benannten Parametern die folgenden zusätzlichen Regeln und Prinzipien:

  • Die tatsächlichen Parameter können in sein jede Reihenfolge bestanden, , aber benannte Argumente können nur am Ende der Argumentliste erscheinen.

  • Parameter ohne Standardwerte können nach Namen übergeben werden, aber alle erforderlichen Argumente müssen übergeben werden (entweder nach Position oder nach Namen).

  • c# lässt nicht zu, dass die tatsächlichen Parameter zwischen Kommas wie M(1,,DateTime.Now) weglassen. Wenn Sie bei Parametern mit Standardwerten deren tatsächliche Parameter weglassen möchten, übergeben Sie einfach die tatsächlichen Parameter, indem Sie den Parameternamen übergeben.

  • Wenn der Parameter ref/out erfordert, verwenden Sie bitte die folgende Syntax, um den tatsächlichen Parameter durch Übergabe des Parameternamens zu übergeben:

        //方法声明:
        private static void M(ref int x) { ...}
    
        //方法调用:
        int a = 5;
        M(x: ref a);
    Nach dem Login kopieren
  • Wenn C# eine COM-Komponente aufruft und tatsächliche Parameter als Referenz übergeben werden, erlaubt C# auch das Weglassen von ref/out, um die Codierung weiter zu vereinfachen. Wenn der Anruf jedoch keine COM -Komponente ist, verlangt C#, dass der Ref/Out -Schlüsselwort auf die tatsächlichen Parameter angewendet werden muss.

9.1.2 DefaultParameterValueAttribute und OptionalAttribute

9.2 Implizit typisierte lokale Variablen

  • Var kann nicht zum Deklarieren des Methodenparametertyps verwendet werden.

  • Sie können VAR nicht verwenden, um Felder in einem Typ zu deklarieren.

  • verwechseln Sie dynamisch nicht mit var . Das Deklarieren lokaler Variablen mit var ist lediglich eine vereinfachte Syntax, die erfordert, dass der Compiler den spezifischen Datentyp basierend auf dem Ausdruck ableitet. Das Schlüsselwort var kann nur lokale Variablen innerhalb einer Methode deklarieren, während das Schlüsselwort dynamic für lokale Variablen, Felder und Parameter gilt. Der Ausdruck kann nicht in var konvertiert werden, kann jedoch in dynamisch konvertiert werden. Mit var deklarierte Variablen müssen explizit initialisiert werden, mit dynamic deklarierte Variablen müssen jedoch nicht initialisiert werden.

        private static void ImplicitlyTypedLocalVariables()
        {
            var name = "Jeff";
            ShowVariableType(name); //显示:System.String

            //var n=null;           //错误,不能将null赋给隐式类型的局部变量
            var x = (String)null;   //可以这样写,但意义不大
            ShowVariableType(x);    //显示:System.String

            var numbers = new int[] { 1, 2, 3, 4 };
            ShowVariableType(numbers);  //显示:System.Int32[]

            //复杂类型能少打一些字
            var collection = new Dictionary<String, Single>() { { "Grant", 4.0f } };

            //显示:System.Collections.Generic.Dictionary`2[System.String,System.Single]
            ShowVariableType(collection);

            foreach (var item in collection)
            {
                //显示:System.Collections.Generic.KeyValuePair`2[System.String,System.Single]
                ShowVariableType(item);
            }
        }

        private static void ShowVariableType<T>(T t)
        {
            Console.WriteLine(typeof(T));
        }
Nach dem Login kopieren

9.3 Übergeben von Parametern an Methoden per Referenz

  • CLR übergibt standardmäßig alle Methodenparameter als Wert.

  • CLR ermöglicht es, Parameter eher mit Referenz als durch Wert zu übergeben. C# unterstützt diese Funktionalität anhand der Schlüsselwörter out oder ref .

  • CLR unterscheidet nicht zwischen out und ref, und unabhängig davon, welches Schlüsselwort verwendet wird, wird derselbe IL-Code generiert. Darüber hinaus sind die Metadaten fast identisch, bis auf ein Bit, mit dem aufgezeichnet wird, ob bei der Deklaration der Methode out oder ref angegeben wurde.

  • Der C#-Compiler behandelt diese beiden Schlüsselwörter unterschiedlich, und dieser Unterschied bestimmt, welche Methode für die Initialisierung des referenzierten Objekts verantwortlich ist.

  • Die Methode, die out zum Markieren des Parameters verwendet, kann den Wert des Parameters nicht lesen und muss vor der Rückgabe auf diesen Wert schreiben. Wenn eine Methode hingegen mit ref markiert ist, muss der Wert des Parameters vor dem Aufruf der Methode initialisiert werden. Die aufgerufene Methode kann den Wert lesen und/oder auf den Wert

    < schreiben 🎜>
  • is used
  • out

        public static void Main()
        {
            int x;                  //x没有初始化
            GetVal(out x);          //x不必初始化
            Console.WriteLine(x);   //显示“10”
        }
    
        private static void GetVal(out int v)
        {
            v = 10; //该方法必须初始化v
        }
    Nach dem Login kopieren
  • using
  • ref

        public static void Main()
        {
            int x = 5;              //x已经初始化
            GetVal(ref x);          //x必须初始化
            Console.WriteLine(x);   //显示“15”
        }
    
        private static void GetVal(ref int v)
        {
            v += 10; //该方法可使用v的已初始化的值
        }
    Nach dem Login kopieren
  • kann nicht nur in überlasteten Ref -Methoden definiert werden, die sich von Out unterscheiden.
  • Die an die Methode übergebene Variable durch Referenz muss vom gleichen Typ wie der in der Methodensignatur deklarierte Typ sein.
  •     public static void Main()
        {
            string s1 = "Jeffrey";
            string s2 = "Richter";
    
            //错误!错误!错误!
            //Swap(ref s1, ref s2);   
    
            //以传引用的方式传递的变量,
            //必须和方法预期的匹配
            object o1 = s1, o2 = s2;
            Swap(ref o1,ref o2);
    
            //完事后再将object转型为string
            s1 = (string)o1;
            s2 = (string)o2;
    
            Console.WriteLine(s1);   //显示“Richter”
            Console.WriteLine(s2);   //显示“Jeffrey”
        }
    
        private static void Swap(ref object a, ref object b)
        {
            object t = b;
            b = a;
            a = t;
        }
    Nach dem Login kopieren
  • Sie können Generika verwenden, um die obige Methode
  • zu ändern
        public static void Main()
        {
            string s1 = "Jeffrey";
            string s2 = "Richter";
    
            Swap(ref s1, ref s2);
            Console.WriteLine(s1);   //显示“Richter”
            Console.WriteLine(s2);   //显示“Jeffrey”
        }
    
        private static void Swap<T>(ref T a, ref T b)
        {
            T t = b;
            b = a;
            a = t;
        }
    Nach dem Login kopieren

9.4 向方法传递可变数量的参数

  • params 只能应用于方法签名中的最后一个参数。

  • 这个参数只能标识一维数组(任意类型)。

  • 可为这个参数传递 null 值,或传递对包含零个元素的一个数组的引用。

  • 调用参数数量可变的方法对性能有所影响(除非显式传递null)。要减少对性能的影响,可考虑定义几个没有使用 params 关键字的重载版本,如System.String类的Concat方法。

        public static void Main()
        {
            Console.WriteLine(Add(new int[] { 1, 2, 3, 4, 5 }));//显示“15”
            //或
            Console.WriteLine(Add(1, 2, 3, 4, 5));              //显示“15”

            //以下两行都显示“0”
            Console.WriteLine(Add());       //向Add传递 new int[0]
            Console.WriteLine(Add(null));   //向Add传递 null :更高效(因为不会分配数组)
        }

        private static int Add(params int[] values)
        {
            // 注意:如果愿意,可将values数组传给其他方法

            int sum = 0;
            if (values != null)
            {
                for (int x = 0; x < values.Length; x++)
                    sum += values[x];
            }
            return sum;
        }
Nach dem Login kopieren

9.5 参数和返回类型的设计规范

  • 声明方法的参数类型时,应尽量指定最弱的类型,宁愿要接口也不要基类。例如,如果要写方法来处理一组数据项,最好是用接口(比如 IEnumerable<T>)声明参数,而不要用强数据类型(比如List<T>)或者更强的接口类型(比如ICollection<T>IList<T>):

        //好:方法使用弱参数类型
        public void ManipulateItems<T>(IEnumerable<T> collection){}
    
        //不好:方法使用强参数类型
        public void ManipulateItems<T>(List<T> collection) { }
    Nach dem Login kopieren
  • 相反,一般最好是将方法的返回类型声明为最强的类型(防止受限于特定类型)。例如,方法最好返回FileStream而不是Stream对象:

        //好:方法使用强返回类
        public FileStream OpenFile() { }
    
        //不好:方法使用弱返回类
        public Stream OpenFile() { }
    Nach dem Login kopieren
  • 如果想保持一定的灵活性,在将来更改方法返回的东西,请选择一个较弱的返回类型。

        //灵活:方法使用较弱的返回类型
        public IList<string> GetStringCollection() { }
    
        //不灵活:方法使用较强的返回类型
        public List<string> GetStringCollection() { }
    Nach dem Login kopieren

    Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung optionaler Parameter und Beispiele benannter Parameter. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage