Lập trình C#

Properties và Indexers trong C#

Properties và Indexers trong C#
Được viết bởi Minh Hoàng

Series lập trình C#, ngôn ngữ lập trình hiện đại và mạnh mẽ.

Trong bài viết này, chúng ta sẽ cùng tìm hiểu PropertiesIndexers trong lập trình hướng đối tượng C#.
Nội dung chính:

  1. Properties
  2. Indexers
1. Properties

1. Properties

Thuộc tínhProperty là một thành viên (member) của một class, struct hay interface. Nó là mở rộng của một trường (field). Property cho phép bạn truy cập vào một field hoặc thay đổi giá trị của field đó, mà không cần thiết phải truy cập trực tiếp vào field.

– Một property là một thành viên cung cấp một cơ chế linh hoạt để đọc, ghi hoặc tính toán giá trị của một private field. Các properties có thể được sử dụng như thể chúng là những public data members, nhưng chúng thực sự là các phương thức đặc biệt (special methods) được gọi là bộ truy cập (accessors). Điều này cho phép dữ liệu được truy cập dễ dàng, linh hoạt mà vẫn đảm bảo được sự an toàn.

Xem thêm: So sánh properties và fields.

– Có 4 loại properties:

  1. Read-Write Property: có đủ phương thức get (để lấy dữ liệu của field), set (để thiết lập dữ liệu cho field).
  2. Read only Property: chỉ có phương thức get.
  3. Write only Property: chỉ có phương thức set.
  4. Auto-Implemented Property: cách viết ngắn gọn của loại 1. Read-Write Property.
    Trong C# 3.0 trở lên, các thuộc tính được implemented tự động làm cho khai báo thuộc tính ngắn gọn hơn khi không có logic bổ sung nào được yêu cầu trong các bộ truy cập (accessors) thuộc tính. Khi bạn khai báo thuộc tính (name2, address2, address3, age2) như trong ví dụ sau, trình biên dịch sẽ tạo một trường (field) sao lưu riêng, ẩn danh (anonymous) chỉ có thể được truy cập thông qua get và set accessors.

– Ví dụ:

namespace MinhHoangBlog
{
	class SampleProperty
	{
		// 1. Read-Write Property
		private string name1;

		public string Name1
		{
			get { return Name1; }

			set { Name1 = value; }
		}

		// 2. Read only Property
		private string address1;

		public string Address1
		{
			get
			{
				return address1;
			}
		}

		// 3. Write only Property
		private int age1;

		public int Age1
		{
			set
			{
				if (1 > value)
					age1 = 1;
				else
					age1 = value;
			}
		}

		// 4. Auto-Implemented Property
		// Cách viết ngắn gọn của // 1. Read-Write Property
		public string name2 { get; set; }

		// Cách viết ngắn gọn của // 2. Read only Property
		public string address2 { get; }
		public string address3 { get; private set; }

		// Write only Property
		public string age2 { private get; set; }
	}
}

Tip: Chọn vào tên field, rồi nhấn tổ hợp phím Ctrl + R + E + Enter để sinh get/set tự động.

2. Indexers

2. Indexers

Indexer cho phép các instances của class hoặc struct được lập chỉ mục (index) giống như các mảng (array), nó cho phép duyệt các đối tượng của một lớp giống như duyệt mảng (bằng cách sử dụng cặp dấu []).

– Một số đặc điểm của indexer:

  • Indexer còn được gọi là smart array (mảng thông minh), hay prototype của tham số.
  • Indexer có thể được nạp chồng (overload).
  • Indexer có thể được include như là một interface member.
  • Indexer không hỗ trợ refout parameter.

Xem thêm: Cách truyền tham trị, tham chiếu trong C#.

– Cú pháp khai báo:

<phạm vi truy cập> <đối tượng dữ liệu> this[<kiểu dữ liệu> index]
{
   get
   {
      // trả về giá trị được xác định bởi index
   }
   
   set
   {
      // thiết lập giá trị được xác định bởi index
   }
}

Sử dụng của Indexer trong C#:

– Việc khai báo hành vi của một indexer là tương tự như một property. Bạn sử dụng get accessor và set accessor để định nghĩa một indexer.

– Việc định nghĩa một property bao gồm việc cung cấp một tên thuộc tính. Indexer không được định nghĩa với các tên, mà với từ khóa this sẽ tham chiếu tới instance của đối tượng. Ví dụ sau đây minh họa khái niệm này:

■ Tạo class Product.cs

namespace MinhHoangBlog
{
	class Product
	{
		public int id { get; set; }
		public string name { get; set; }
	}
}

■ Tạo class ProductList.cs

namespace MinhHoangBlog
{
	class ProductList
	{
		public Product[] arrProduct { get; set; }

		// Indexer
		public Product this[int index]
		{
			get
			{
				if (0 > index || index >= arrProduct.Length)
					//return null;
					throw new IndexOutOfRangeException("Index not valid!!!");

				else
					return arrProduct[index];
			}
			set
			{
				if (0 > index || index >= arrProduct.Length)
					throw new IndexOutOfRangeException("Index not valid!!!");
				else
					arrProduct[index] = value;
			}
		}

		// Overload indexer, nhận vào 1 biến kiểu string
		// Để search trong list product,
		// có tên sản phẩm trùng với tên sản phẩm user input vào hay không.
		public Product this[string name]
		{
			get
			{
				for (int ii = 0; ii < arrProduct.Length; ii++)
				{
					if (arrProduct[ii].name.ToUpper().Equals(name.ToUpper()))
					{
						return arrProduct[ii];
					}
				}

				return null;
			}
		}
	}
}

■ Class xử lý chính Program.cs

using System;

namespace MinhHoangBlog
{
	class Program
	{
		static void Main(string[] args)
		{
			// Tạo đối tượng list sản phẩm
			ProductList pList = new ProductList();

			// Trong danh sách sp này sẽ có 5 sản phẩm
			pList.arrProduct = new Product[5];

			// ★ Dùng theo cách thông thường
			/*
            for (int ii = 0; ii < pList.arrProduct.Length; ii++)
            {
                //Đối với mỗi sp thứ i thì set thông tin
                pList.arrProduct[ii] = new Product();
                pList.arrProduct[ii].id = ii;
                pList.arrProduct[ii].name = string.Format("P{0}", ii);
            }

            // In thông tin SP
            for (int ii = 0; ii < pList.arrProduct.Length; ii++)
            {
                Console.WriteLine("id: " + pList.arrProduct[ii].id);
                Console.WriteLine("name: " + pList.arrProduct[ii].name);
                Console.WriteLine("----------------------");
            }
			*/

			// ★ Dùng Indexer
			for (int ii = 0; ii < pList.arrProduct.Length; ii++)
			{
				pList[ii] = new Product();
				pList[ii].id = ii;
				pList[ii].name = string.Format("P{0}", ii);
			}

			// In thông tin SP
			for (int ii = 0; ii < pList.arrProduct.Length; ii++)
			{
				Console.WriteLine("id: " + pList[ii].id);
				Console.WriteLine("name: " + pList[ii].name);
				Console.WriteLine("----------------------\n");
			}

			// ★ Dùng overload Indexer
			Console.Write("Nhap vao ten san pham: ");
			string name = Console.ReadLine();

			Product sanpham = pList[name];
			if (null != sanpham)
			{
				Console.WriteLine("TIM THAY SAN PHAM!");
			}
			else
			{
				Console.WriteLine("KHONG TIM THAY.");
			}

			Console.ReadKey();
		}
	}
}
Kết quả chương trình

Kết quả chương trình

Cảm ơn bạn đã theo dõi. Đừng ngần ngại hãy cùng thảo luận với chúng tôi!

Giới thiệu

Minh Hoàng

Xin chào, tôi là Hoàng Ngọc Minh, hiện đang làm BrSE, tại công ty Toyota, Nhật Bản. Những gì tôi viết trên blog này là những trải nghiệm thực tế tôi đã đúc rút ra được trong cuộc sống, quá trình học tập và làm việc. Các bài viết được biên tập một cách chi tiết, linh hoạt để giúp người đọc có thể tiếp cận một cách dễ dàng nhất. Hi vọng nó sẽ có ích hoặc mang lại một góc nhìn khác cho bạn[...]

Bình luận của bạn

avatar

Properties và Indexers trong C#

by Minh Hoàng Time to read: 5 min
0