선택적 매개변수 및 명명된 매개변수 예에 대한 자세한 설명

零下一度
풀어 주다: 2017-06-24 09:46:31
원래의
2454명이 탐색했습니다.

9.1 선택적 및 명명된 매개변수

    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++);
        }
    }
로그인 후 복사

9.1.1 규칙 및 원칙

  • 기본값은 메서드의 매개변수, 생성자 메서드 및 매개변수화된 속성(C# 인덱서)에 대해 지정할 수 있습니다. 위임 정의의 일부인 매개변수에 대한 기본값을 지정할 수도 있습니다.

  • 기본값이 있는 매개변수는 기본값이 없는 모든 매개변수 뒤에 배치되어야 합니다. 그러나 한 가지 예외가 있습니다. "매개변수 배열"과 같은 매개변수는 모든 매개변수(기본값이 있는 매개변수 포함) 뒤에 배치되어야 하며 배열 자체는 기본값을 가질 수 없습니다.

  • 기본값은 컴파일 타임에 결정될 수 있는 상수 값이어야 합니다(기본 유형, 열거 유형 및 null로 설정될 수 있는 모든 참조 유형 포함). 값 유형의 매개변수는 기본값을 값 유형의 인스턴스로 설정하고 해당 필드의 모든 값이 0이 되도록 합니다. default 또는 new 키워드를 사용하여 이 의미를 표현할 수 있습니다. 두 구문으로 생성된 IL 코드는 완전히 동일합니다.

  • 매개변수 변수의 이름을 바꾸지 마세요. 그렇지 않으면 매개변수 이름으로 실제 매개변수를 전달하는 호출자도 코드를 수정해야 합니다.

  • 메서드가 모듈 외부에서 호출되는 경우 매개변수의 기본값을 변경하는 것은 잠재적으로 위험할 수 있습니다. 호출 사이트(호출이 이루어지는 곳)는 호출에 기본값을 포함합니다. 나중에 매개변수의 기본값을 변경했지만 호출 사이트가 포함된 코드를 다시 컴파일하지 않으면 메서드를 호출할 때 이전 기본값이 전달됩니다. 기본 동작을 나타내기 위해 기본값 0/null을 센티널 값으로 사용하는 것을 고려하세요. 예:

        //不要这样做:
        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");
        }
    로그인 후 복사
  • 매개변수에 ref 또는 out 키워드가 표시되면 기본값을 설정할 수 없습니다.

선택적 또는 명명된 매개변수가 있는 메서드를 호출할 때 다음 추가 규칙과 원칙에도 주의하세요.

  • 실제 매개변수는 순서에 관계없이 전달될 수 있습니다. 그러나 명명된 실제 매개변수는 실제 매개변수 목록 끝 .

  • 기본값이 없는 매개변수는 이름으로 전달될 수 있지만 모든 필수 인수는 위치 또는 이름으로 전달되어야 합니다.

  • C#에서는 M(1,,DateTime.Now)와 같이 쉼표 사이에 실제 매개변수를 생략하는 것이 허용되지 않습니다. 기본값이 있는 매개변수의 경우 실제 매개변수를 생략하려면 매개변수 이름을 전달하여 실제 매개변수를 전달하면 됩니다.

  • 매개변수에 ref/out이 필요한 경우 매개변수 이름을 전달하여 실제 매개변수를 전달하려면 다음 구문을 사용하세요.

        //方法声明:
        private static void M(ref int x) { ...}
    
        //方法调用:
        int a = 5;
        M(x: ref a);
    로그인 후 복사
  • C#에서 COM 구성 요소를 호출할 때 reference 실제 매개변수를 전달할 때 C#에서는 ref/out을 생략할 수 있으므로 코딩이 더욱 단순화됩니다. 그러나 호출이 COM 구성 요소가 아닌 경우 C#에서는 ref/out 키워드를 실제 매개 변수에 적용해야 합니다.

9.1.2 DefaultParameterValueAttribute 및 OptionalAttribute

9.2 암시적으로 유형이 지정된 지역 변수

  • var를 사용하여 메서드의 매개 변수 유형을 선언할 수 없습니다.

  • var를 사용하여 유형의 필드를 선언할 수 없습니다.

  • dynamicvar을 혼동하지 마세요. var을 사용하여 지역 변수를 선언하는 것은 컴파일러가 표현식을 기반으로 특정 데이터 유형을 유추하도록 요구하는 단순화된 구문일 뿐입니다. var 키워드는 메서드 내에서 지역 변수만 선언할 수 있는 반면, dynamic 키워드는 지역 변수, 필드 및 매개변수에 적용됩니다. 표현식은 var 로 변환할 수 없지만 dynamic 으로 변환할 수 있습니다. var로 선언된 변수는 명시적으로 초기화되어야 하지만 dynamic로 선언된 변수는 초기화할 필요가 없습니다.

        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));
        }
로그인 후 복사

9.3 매개변수를 참조로 메서드에 전달

  • CLR은 기본값으로 값으로 전달되는 모든 메서드 매개변수를 사용합니다.

  • CLR을 사용하면 매개변수를 값이 아닌 참조로 전달할 수 있습니다. C#에서는 out 또는 ref 키워드를 사용하여 이 기능을 지원합니다.

  • CLR은 outref을 구분하지 않으므로 어떤 키워드를 사용하더라도 동일한 IL 코드가 생성됩니다. 또한 메소드 선언 시 out 또는 ref 지정 여부를 기록하는 데 사용되는 1비트를 제외하면 메타데이터는 거의 동일합니다.

  • C# 컴파일러는 이 두 키워드를 다르게 처리하며, 이 차이점에 따라 참조된 개체 초기화를 담당하는 메서드가 결정됩니다.

  • 매개변수를 표시하기 위해 out을 사용하는 메서드는 매개변수의 값을 읽을 수 없으며 반환하기 전에 이 값에 써야 합니다. 반대로 메소드를 ref로 표시하면 메소드를 호출하기 전에 매개변수 값을 초기화해야 합니다. 호출된 메소드는 값을 읽거나 값에 를 쓸 수 있습니다. ref와 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
        }
    로그인 후 복사

  • 제네릭을 사용하여 위 방법을 수정할 수 있습니다
  •     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;
        }
    로그인 후 복사

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;
        }
로그인 후 복사

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

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

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

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

        //灵活:方法使用较弱的返回类型
        public IList<string> GetStringCollection() { }
    
        //不灵活:方法使用较强的返回类型
        public List<string> GetStringCollection() { }
    로그인 후 복사

    위 내용은 선택적 매개변수 및 명명된 매개변수 예에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿