由一系列以执行特定的操作或计算结果语句组成。方法总是和类关联,类型将相关的方法分为一组。
一种分类机制,用于组合功能相关的所有类型。命名空间是分级的,级数可以是任意。 命名空间层级一般从公司名开始,然后是产品名,最后是功能领域,例如:
主要用于按照功能领域组织,以便更容易查找和理解它们。除此之外,命名空间还有助于防止类型名称发生冲突.
表达式主体成员提供了一种更简洁、更可读的成员实现
Member | Supported as of... |
Method | C# 6 |
Constructor | C# 7 |
Finalizer | C# 7 |
Property Get | C# 6 |
Property Set | C# 7 |
Indexer | C# 7 |
语法:member => expression
表达式主体方法使用箭头操作符 (=>) 将单个表达式分配到一个属性或方法来替代语句体 ,如果方法有返回值, 该表达式返回值必须与方法返回类型相同;如果方法无返回值,则表达式执行一系列操作。
- public class Person
- {
- public Person(string firstName, string lastName)
- {
- fname = firstName;
- lname = lastName;
- }
- private string fname;
- private string lname;
- public override string ToString() => $"{fname} {lname}".Trim();
- public void DisplayName() => Console.WriteLine(ToString());
- }
C# 不支持全局方法,所有方法都必须在某个类型中。
- public class Program
- {
- public static void ChapterMain()
- {
- string firstName, lastName, fullName, initials;
- System.Console.WriteLine("Hey you!");
- firstName = GetUserInput("Enter your first name: ");
- lastName = GetUserInput("Enter your last name: ");
- fullName = GetFullName(firstName, lastName);
- initials = GetInitials(firstName, lastName);
- DisplayGreeting(fullName, initials);
- }
- static string GetUserInput(string prompt)
- {
- System.Console.Write(prompt);
- return System.Console.ReadLine();
- }
- static string GetFullName( string firstName, string lastName) => $"{ firstName } { lastName }";
- static void DisplayGreeting(string fullName, string initials)
- {
- System.Console.WriteLine($"Hello { fullName }! Your initials are { initials }");
- }
- static string GetInitials(string firstName, string lastName)
- {
- return $"{ firstName[0] }. { lastName[0] }.";
- }
- }
C# 支持在执行程序时提供命令行参数,并运行从Main() 方法返回状态标识符,当需要从非Main()方法中访问命令行参数时, 可用System.Environment.GetcommandLineArgs() 方法:
- public static int Main(string[] args)
- {
- int result;
- string targetFileName, string url;
- switch(args.Length)
- {
- default:
- Console.WriteLine("ERROR: You must specify the "+ "URL and the file name"); // Exactly two arguments must be specified; give an error.
- targetFileName = null;
- url = null;
- break;
- case 2:
- url = args[0];
- targetFileName = args[1];
- break;
- }
- if(targetFileName != null && url != null)
- {
- using (HttpClient httpClient = new HttpClient())
- using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url))
- using (HttpResponseMessage message = httpClient.SendAsync(request).Result)
- using (Stream contentStream = message.Content.ReadAsStreamAsync().Result)
- using (FileStream fileStream = new FileStream(targetFileName, FileMode.Create, FileAccess.Write, FileShare.None))
- {
- contentStream.CopyToAsync(fileStream);
- }
- return 0;
- }
- Console.WriteLine("Usage: Downloader.exe
" ); - return 1;
- }
C# 中,参数传递默认是值传递的, 也就是说,参数表达式的值会复制到目标参数中。
- public static void ChapterMain()
- {
- string fullName;
- string driveLetter = "C:";
- string folderPath = "Data";
- string fileName = "index.html";
- fullName = Combine(driveLetter, folderPath, fileName);
- Console.WriteLine(fullName);
- }
- static string Combine(string driveLetter, string folderPath, string fileName)
- {
- string path;
- path = string.Format("{1}{0}{2}{0}{3}", System.IO.Path.DirectorySeparatorChar, driveLetter, folderPath, fileName);
- return path;
- }
- class RefExample
- {
- static void Method(ref int i)
- {
- i = i + 44;
- }
- static void Main()
- {
- int val = 1;
- Method(ref val);
- Console.WriteLine(val); // Output: 45
- }
- }
- class RefExample2
- {
- static void Main()
- {
- Product item = new Product("Fasteners", 54321);// Declare an instance of Product and display its initial values.
- System.Console.WriteLine("Original values in Main. Name: {0}, ID: {1}\n", item.ItemName, item.ItemID);
- ChangeByReference(ref item); // Pass the product instance to ChangeByReference.
- System.Console.WriteLine("Back in Main. Name: {0}, ID: {1}\n", item.ItemName, item.ItemID);
- }
- static void ChangeByReference(ref Product itemRef)
- {
- // Change the address that is stored in the itemRef parameter.
- itemRef = new Product("Stapler", 99999);
- itemRef.ItemID = 12345;
- }
- }
- class Product
- {
- public Product(string name, int newID)
- {
- ItemName = name;
- ItemID = newID;
- }
- public string ItemName { get; set; }
- public int ItemID { get; set; }
- }
- class OutReturnExample
- {
- static void Method(out int i, out string s1, out string s2)
- {
- i = 44;
- s1 = "I've been returned";
- s2 = null;
- }
- static void Main()
- {
- int value;
- string str1, str2;
- Method(out value, out str1, out str2);
- }
- }
通过在方法参数前显式指定 param, C# 允许在调用方法时提供可变数量参数
- public static void ChapterMain()
- {
- string fullName;
- fullName = Combine(Directory.GetCurrentDirectory(), "bin", "config", "index.html"); // Call Combine() with four parameters
- Console.WriteLine(fullName);
- fullName = Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "Temp", "index.html"); // Call Combine() with only three parameters
- Console.WriteLine(fullName);
- fullName = Combine( new string[] {$"C:{Path.DirectorySeparatorChar}", "Data", "HomeDir", "index.html" }); // Call Combine() with an array
- 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;
- }
调用者显式地为一个参数赋值
- static void Main(string[] args)
- {
- PrintOrderDetails("Gift Shop", 31, "Red Mug"); // The method can be called in the normal way, by using positional arguments.
- // Named arguments can be supplied for the parameters in any order.
- PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
- PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);
- // Named arguments mixed with positional arguments are valid as long as they are used in their correct position.
- PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
- // However, mixed arguments are invalid if used out-of-order. The following statements will cause a compiler error.
- // PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");
- // PrintOrderDetails(31, sellerName: "Gift Shop", "Red Mug");
- // PrintOrderDetails(31, "Red Mug", sellerName: "Gift Shop");
- }
- static void PrintOrderDetails(string sellerName, int orderNum, string productName)
- {
- if (string.IsNullOrWhiteSpace(sellerName))
- throw new ArgumentException(message: "Seller name cannot be null or empty.", paramName: nameof(sellerName));
- Console.WriteLine($"Seller: {sellerName}, Order #: {orderNum}, Product: {productName}");
- }
可选参数例子:
- static void Main(string[] args)
- {
- // Instance anExample does not send an argument for the constructor‘s optional parameter.
- ExampleClass anExample = new ExampleClass();
- anExample.ExampleMethod(1, "One", 1);
- anExample.ExampleMethod(2, "Two");
- anExample.ExampleMethod(3);
- // Instance anotherExample sends an argument for the constructor‘s optional parameter.
- ExampleClass anotherExample = new ExampleClass("Provided name");
- anotherExample.ExampleMethod(1, "One", 1);
- anotherExample.ExampleMethod(2, "Two");
- anotherExample.ExampleMethod(3);
-
- // You cannot leave a gap in the provided arguments.
- //anExample.ExampleMethod(3, ,4);
- //anExample.ExampleMethod(3, 4);
- // You can use a named parameter to make the previous statement work.
- anExample.ExampleMethod(3, optionalint: 4);
- }
- class ExampleClass
- {
- private string _name;
- public ExampleClass(string name = "Default name")
- {
- _name = name;
- }
- public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10)
- {
- Console.WriteLine("{0}: {1}, {2}, and {3}.", _name, required, optionalstr, optionalint);
- }
- }
类似于C++, C# 也支持方法重载。C# 根据参数类型和参数个数选择最匹配的方法
命名参数和可选参数影响重载规则