ใน C# เมธอดส่วนใหญ่สามารถมีพารามิเตอร์ตั้งแต่ศูนย์ขึ้นไป ซึ่งกำหนดข้อมูลที่ต้องระบุให้กับเมธอด รหัสใด ๆ ที่เรียกใช้เมธอดจะต้องส่งข้อมูล (เรียกว่าอาร์กิวเมนต์) ไปยังเมธอด เมธอดประกาศอินพุตเป็นพารามิเตอร์ และจัดเตรียมโดยการเรียกโค้ดในรูปแบบของอาร์กิวเมนต์
ตัวอย่างเช่น พิจารณาเมธอดต่อไปนี้และการเรียกเมธอดที่ตามมา
static void Greet(string greeting){ Console.WriteLine(greeting); } ... Greet("Hello");
ในตัวอย่างข้างต้น การทักทายเป็นพารามิเตอร์ของวิธีการ Greet() และ "สวัสดี" เป็นอาร์กิวเมนต์ที่ส่งผ่านไปยังวิธีการนั้น
เมื่อคุณเรียกใช้เมธอดและส่งอาร์กิวเมนต์ อาร์กิวเมนต์จะถูกส่งผ่าน ซึ่งหมายความว่าสำเนาของค่าจะถูกสร้างขึ้นเมื่อส่งผ่านไปยังเมธอด การเปลี่ยนแปลงใดๆ ที่เกิดขึ้นกับอาร์กิวเมนต์ภายในเมธอดจะไม่มีผลกับตัวแปรเดิม
using System; int number = 8; Increase(number); Console.WriteLine(number); // prints 8 static void Increase(int num){ num = num + 1; Console.WriteLine(num); // prints 9 }
เมื่อคุณส่งตัวแปรประเภทการอ้างอิง เช่น อ็อบเจ็กต์ C# จะยังคงคัดลอก การอ้างอิง ตามค่า เนื่องจากตัวแปรถือการอ้างอิง ไม่ใช่วัตถุจริง ดังนั้นแม้ว่าสำเนาของตัวแปรอ้างอิงจะถูกส่งต่อ ทั้งคู่อ้างถึงวัตถุเดียวกันในหน่วยความจำ ดังนั้นการเปลี่ยนแปลงใดๆ ที่ทำกับวัตถุโดยตัวแปรภายในเมธอดนั้น ตัวแปรภายนอกเมธอดจะมองเห็นได้
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 60000 static void Promote(User u){ u.Salary += 10000; Console.WriteLine(u.Salary); // prints 60000 }
อย่างไรก็ตาม หากคุณเปลี่ยนค่าของตัวแปรเองภายในเมธอด การเปลี่ยนแปลงนั้นจะไม่มีผลภายนอกเมธอด เนื่องจากมีเพียงสำเนาเท่านั้นที่เปลี่ยน ไม่ใช่อ็อบเจกต์จริง ตัวอย่างเช่น เราสามารถกำหนดอาร์กิวเมนต์เป็น null ภายในเมธอด และตัวแปรจริงจะไม่เปลี่ยนแปลง
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 50000 static void Promote(User u){ u = null; }
C# อนุญาตให้ใช้คีย์เวิร์ดตัวปรับแต่งที่แตกต่างกันสามคำ ซึ่งคุณสามารถควบคุมพารามิเตอร์ของเมธอดได้
ตัวแก้ไขการอ้างอิง
C # อนุญาตให้คุณส่งผ่านพารามิเตอร์โดยการอ้างอิงโดยใช้ ref ตัวแก้ไข ไม่สำคัญว่าตัวแปรที่ส่งผ่านจะเป็นของประเภทอ้างอิงหรือประเภทค่า ทั้งพารามิเตอร์และอาร์กิวเมนต์จะอ้างอิงถึงตำแหน่งหน่วยความจำเดียวกัน
ในตัวอย่างต่อไปนี้ การตั้งค่าอาร์กิวเมนต์ u เป็น null จะทำให้ตัวแปร john เป็น null ทำให้เกิดข้อยกเว้นการอ้างอิง null
ตัวอย่าง
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(ref john); Console.WriteLine(john.Salary); // throws System.NullReferenceException static void Promote(ref User u){ u = null; }
อาร์กิวเมนต์ที่ส่งผ่านด้วยตัวแก้ไขการอ้างอิงจะต้องเริ่มต้นก่อนที่จะส่งผ่าน
ตัวแก้ไขสัญญาณออก
คล้ายกับตัวแก้ไขการอ้างอิง ยกเว้น
-
อาร์กิวเมนต์ไม่จำเป็นต้องเริ่มต้นก่อนที่จะเข้าสู่ฟังก์ชัน
-
อาร์กิวเมนต์ต้องเริ่มต้น (กำหนดให้กับ) ก่อนจึงจะออกจากฟังก์ชันได้
ในตัวอย่างด้านล่าง ฟังก์ชัน Hire จะเริ่มต้นวัตถุผู้ใช้ใหม่ที่ส่งผ่านไปยังตัวแก้ไขการเอาท์ โปรดสังเกตว่าตัวแปรคือตัวแปร john ถูกประกาศทันทีเมื่อเรียกใช้เมธอด Hire
using System; Hire(out User john); Console.WriteLine(john.Salary); // prints 50000 static void Hire(out User u){ u = new User{ Name = "John", Salary = 50000 }; }
ชอบ ผู้อ้างอิง ตัวแก้ไข ตัวแปรที่ทำเครื่องหมายโดย ออก ตัวดัดแปลงถูกส่งผ่านโดยการอ้างอิง
มักจะ ออก ตัวแปรถูกใช้เพื่อรับค่าส่งคืนหลายค่าจากฟังก์ชันดังนี้ -
using System; var john = new User{ Name = "John", Salary = 50000 }; bool shouldPromote = Raise(john.Salary, out double hike); Console.WriteLine(shouldPromote); // True Console.WriteLine($"Hike Amount = {hike}"); // prints 5000 static bool Raise(int salary, out double hike){ hike = salary * 0.1; return hike < 7000; }
ตัวแก้ไขใน
คล้ายกับ ref และ ออก พารามิเตอร์ ยกเว้นวิธีการที่ยอมรับ ใน ค่าของอาร์กิวเมนต์ไม่สามารถแก้ไขอาร์กิวเมนต์ได้ หากพยายาม คอมไพเลอร์ C# จะสร้างข้อผิดพลาดในการคอมไพล์
ใน พารามิเตอร์จะบันทึกคอมไพเลอร์จากการคัดลอกหน่วยความจำของประเภทค่าขนาดใหญ่ไปยังตัวแปรพารามิเตอร์ ในขณะเดียวกันก็ป้องกันอ็อบเจ็กต์จากการดัดแปลงโดยไม่ได้ตั้งใจ สิ่งนี้ทำให้มีประโยชน์มากเมื่อส่งประเภทค่าขนาดใหญ่ไปยังเมธอด
var point = new Coord(); Verify(point); static void Verify(in Coord c){ // error: Cannot assign to variable 'in Coord' because it is a readonly variable c = new Coord(); } struct Coord{ public int X; public int Y; }
ตัวอย่าง
using System; class Program{ static void Main(){ int number = 8; Increase(number); Console.WriteLine(number); // prints 8 var john = new User { Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 60000 Leave(john); Console.WriteLine(john.Salary); // prints 60000 LeaveByRef(ref john); Console.WriteLine(john?.Salary); // prints nothing User dave; Hire(out dave); Console.WriteLine(dave.Salary); // prints 50000 } static void Increase(int num){ num = num + 1; Console.WriteLine(num); // prints 9 } static void Promote(User u){ u.Salary += 10000; Console.WriteLine(u.Salary); // prints 60000 } static void Leave(User u){ u = null; } static void LeaveByRef(ref User u){ u = null; } static void Hire(out User u){ u = new User{ Name = "John", Salary = 50000 }; } } class User{ public string Name { get; set; } public int Salary { get; set; } }
ผลลัพธ์
9 8 60000 60000 60000 50000