Essential C # [five] methods and parameters

Front four blog introduces the basic operation content, do not understand before containing cold knowledge, as well as some newly acquired C # newer versions of new knowledge, to be a simple summary:

  • New knowledge : tuples, tryParse (out can be inline), the string interpolation, air union operator, the operator empty condition, may empty modifiers, switch pattern matching
  • Cold knowledge : the type with a single row assignment statement, immutable string, the string resides technology, operator precedence, pre-compiler directive

For individuals or small helpful, at least to see some strange symbols similar ?? not say know. From the beginning of this blog, understand the call and parameters of the method, the practice still, knowing how to adjust the method, they still use old and new knowledge.

The new school concept

The method includes some form of a variety of parameters, form of delivery.

Passed value type reference in

Three categories of reference parameters and returns a reference: ref, out, in, returns a reference:

1, the ref embodiment , a value can be passed by reference to the type of transmission, can be seen in IL code, an address is transferred (point values) rather than copying the value, the value can be changed in this way, the value types can use the same type as the reference, the assignment must be noted that before the reference type by value! , Ref just assign an alias for an existing variable, rather than create a new variable and copy the value argument to it.

  public static void Main()
      {
          // ...
          int first = 5;
          int second = 6;
          Swap(ref first, ref second);

          System.Console.WriteLine(
              $@"first = ""{ first }"", second = ""{ second }""");
          // ...
      }

      private static void Swap(ref int x, ref int y)
      {
          int temp = x;
          x = y;
          y = temp;
      }
  }  //交换first和second的值:first为6,second为5, 如果是值类型,其不会变

2, the use of out the way , C # 7.0 type start out without prior declaration, similar to the usage and ref, to note that, out parameters that must be evaluated in the method

  public static int Main(string[] args)
        {
            if(args.Length == 0)
            {
                Console.WriteLine(
                    "ConvertToPhoneNumber.exe <phrase>");
                Console.WriteLine(
                    "'_' indicates no standard phone button");
                return 1;
            }
            foreach(string word in args)
            {
                foreach(char character in word)
                {
#if !PRECSHARP7   //预编译指令,用来区分环境,只有7.0以上版本才允许使用内联而不用提前声明
                    if(TryGetPhoneButton(character, out char button))
#else
                    char button;
                    if(TryGetPhoneButton(character, out button))
#endif // PRECSHARP7
                    {
                        Console.Write(button);
                    }
                    else
                    {
                        Console.Write('_');
                    }
                }
            }
            Console.WriteLine();
            return 0;
        }

3, the use of in the way , not only can make the type of value passed by reference, and can not be modified method is called value types .

 private void Method(in int number) { }

4, returns a reference: the new version 7.0 , you can return to a variable reference, he said after the usual array processing method is changed, the value of which will not be changed, but returns a reference to the premise can not come into contact with the operating variables in the array, directly modify array element, because it holds the reference to the element ah

 public class Program
    {
        // Returning a reference
        static public ref byte FindFirstRedEyePixel(byte[] image)
        {
            // Do fancy image detection perhaps with machine learning
            for (int counter = 0; counter < image.Length; counter++)
            {
                if (image[counter] == (byte)ConsoleColor.Red)
                {
                    return ref image[counter];
                }
            }
            throw new InvalidOperationException("No pixels are red.");
        }
        public static void Main()
        {
            byte[] image = null;
            // Load image
            image = new byte[42];
            for (int i = 0; i < image.Length; i++)
            {
                image[i] = (byte)ConsoleColor.Black;
            }
            image[(new Random()).Next(0, image.Length - 1)] = (byte)ConsoleColor.Red;

            // Obtain a reference to the first red pixel
            ref byte redPixel = ref FindFirstRedEyePixel(image);
            // Update it to be Black
            redPixel = (byte)ConsoleColor.Black;
            System.Console.WriteLine((ConsoleColor)image[redPixel]); //byte数组里第一个元素颜色被更新为黑色
        } 
    }

Use contraindications: only return a reference to a field or array elements, or other methods returns the attribute references, the method returns a reference to pass as a parameter reference ( Image ).

An array of arguments, parameters can be empty and named parameters

Three kinds of dynamic ways to use parameters: an array of arguments, optional parameters and named parameters.

1, an array of arguments to support the array passed as a parameter, there is a benefit that can make full use of these parameters:

 public class Program
    {
        public static void Main()
        {
            string fullName;

            // ...

            // Call Combine() with four parameters
            fullName = Combine(
                Directory.GetCurrentDirectory(),
                "bin", "config", "index.html");
            Console.WriteLine(fullName);

            // ...

            // Call Combine() with only three parameters
            fullName = Combine(
                Directory.GetParent(Directory.GetCurrentDirectory()).FullName,
                "Temp", "index.html");
            Console.WriteLine(fullName);

            // ...

            // Call Combine() with an array
            fullName = Combine(
                new string[] {
                    $"C:{Path.DirectorySeparatorChar}", "Data",
                    "HomeDir", "index.html" });
            Console.WriteLine(fullName);
            // ...
        }

        static string Combine(params string[] paths)
        {
            string result = string.Empty;
            foreach(string path in paths)
            {
                result = System.IO.Path.Combine(result, path);  //将一系列参数拼接为一个完整路径
            }
            return result;
        }
    }

I would feel more suitable for a certain type of parameters as an array, the clustering effect of it. Note that if you want to use a parameter array to put a final list of parameters .

2, optional parameter usage is usually assigned to the parameter default values when using the optional parameter if you do not pass a value to the default value. Note that if you want to use an empty parameter, the parameter list to put the last one, the default value must be a constant or can be determined at compile-time value .

 static int DirectoryCountLines(
            string directory, string extension = "*.cs")
        {
            int lineCount = 0;
            foreach(string file in
                Directory.GetFiles(directory, extension))
            {
                lineCount += CountLines(file);
            }

            foreach(string subdirectory in
                Directory.GetDirectories(directory))
            {
                lineCount += DirectoryCountLines(subdirectory);
            }

            return lineCount;
        }

3, named parameters, the caller can use named parameters display the specified value , but there are limits, if the parameter name changes, the code will complain

 public class Program
    {
        public static void Main()
        {
            DisplayGreeting(
                firstName: "Inigo", lastName: "Montoya");
        }

        public static void DisplayGreeting(
            string firstName,
            string middleName = default(string),
            string lastName = default(string))
        {
            // ...
        }
    }

It is worth noting that optional parameters, named parameters, method overloading these methods may cause can not distinguish between a method, this time will give priority to the most specific method, there is the order: For example, method overloading, int than long specifically, long specific than double, and so on . There is, if both methods have the same argument, but a use optional parameters, then use another priority, because the compiler uses only parameters caller explicitly identified.

C # cold knowledge

1, although the fully qualified name of the method include: . Namespace type the name of the method name , it is assumed that method to invoke the method call in the same namespace, there is no need to specify the namespace issue method to invoke empathy and the calling method in the same type where not only do not need to specify the namespace, and no need to specify the type name .

2, you can not declare a local variable with the same name and parameters in the method .

3, nested namespace must appear import! , For example, want to use the StringBuilder, although added using System, but still need a using System.Text, which explains the doubts before.

using System;   //不必须
using System.Text;

namespace ClassLibrary1
{
    public class Class1
    {
        private StringBuilder stringBuilder = new StringBuilder();
    }
}

4, using command allows you to omit the namespace, while using static allows you to omit the namespace and type name, simply write the name of the static member . It is understood that because the static method does not allow duplicate.

5, using a namespace using directive class or an alias , collisions can be avoided (both the Timer class and the System.Threading System.Timers), for example, where Timer CountDownTimerd type to use instead.

namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_10
{
    using System;
    using System.Threading;  //该命名空间下也包含Timer类
    using CountDownTimer = System.Timers.Timer;  //别名

    public class HelloWorld
    {
        public static void Main()
        {
            CountDownTimer timer;

            // ...
        }
    }
}

6, although the C # allowed to return in advance, but in order to enhance readability, the exit should determine a single location, rather than on each spread return route method.

7, the method depends on the uniqueness of the method name, parameter type and the number of parameter differences .

8, an abnormality should be captured by a particular sequence is not particularly to:

 public static void Main()
  {
      try
      {
          Console.WriteLine("Begin executing");
          Console.WriteLine("Throw exception");
          throw new Exception("Arbitrary exception");
                Console.WriteLine("End executing");
            }
      catch(FormatException exception)
      {
          Console.WriteLine(
              "A FormatException was thrown");
      }
      catch(Exception exception)
      {
          Console.WriteLine(
              $"Unexpected error: { exception.Message }");
          throw;
      }
      catch
      {
          Console.WriteLine("Unexpected error!");
      }
  
      Console.WriteLine(
          "Shutting down...");
  }

Note that, C # assembly regardless of the type derived from System.Exception will show and from as derived from System.Exception
Here Insert Picture Description

9, to use an empty throw statement at the time of capture and re-throw an exception, in order to preserve the call stack information.

New knowledge of C #

1, although the method can only return a value, but may be utilized tuples, a plurality of return:

     static (string First, string Last) GetName()
        {
            string firstName, lastName;
            firstName = GetUserInput("Enter your first name: ");
            lastName = GetUserInput("Enter your last name: ");
            return (firstName, lastName);
        }

2, the expression thematic approach, if the method simply returns a simple statement in this way, you can use this method:

private static string GetFullName(string firstName, string lastName) => $"{firstName}{lastName}";

3, the best core functionality into a single method for other overloaded method call .

Published 240 original articles · won praise 114 · views 180 000 +

Guess you like

Origin blog.csdn.net/sinat_33087001/article/details/103411872