Cấp bậc tác giả:

TRAINING

Một số điểm trong C# 3.0

Được viết bởi QuangIT ngày 07/05/2013 lúc 12:55 PM
Các ngôn ngữ lập trình của Microsoft đã trở nên phổ biến và được sử dụng rộng rãi do những tính chất mạnh mẽ, những kỹ thuật mới trong lập trình và cú pháp lệnh.
  • 0
  • 2009

Một số điểm trong C# 3.0


Các ngôn ngữ lập trình của Microsoft đã trở nên phổ biến và được sử dụng rộng rãi do những tính chất mạnh mẽ, những kỹ thuật mới trong lập trình và cú pháp lệnh. Xu hướng hiện nay của các ngôn ngữ này là giảm bớt lượng mã lệnh, tận dụng cách viết mã dạng inline và những cú pháp lập trình mới, điều này giúp cho lập trình viên tiết kiệm được khá nhiều thời gian để viết và quản lý mã nguồn.

Bài viết này sẽ trình bày một số điểm liên quan đến cú pháp mã lệnh trong C# 3.0 tương ứng với phiên bản Visual Studio 2008.  Để thực hành các ví dụ sau, bạn cần cài đặt .Net frameword 3.0 trở lên, sử dụng Visual Studio 2008 hoặc Visual C# Express 2008 hay một trình soạn thảo văn bản (nên có hỗ trợ biên dịch C#).

1.    Tự động hiện thực các thuộc tính
(Auto implemented properties)

Một việc làm khá nhàm chán mà các lập trình viên hay phải làm sau khi tạo lớp là viết những accessor (còn gọi là setter, getter trong Java) hay có thể hiểu là các property của đối tượng. Trong C# cũng cung cấp sẵn chức năng tự động tạo ra các accessor từ các field (có thể hiểu là biến toàn cục trong lớp) có sẵn thông qua menu Refactor> Encapsulate Field…

Tuy nhiên có lẽ điều này vẫn chưa đủ, vì thế trong phiên bản 3.0 đã có một cải tiến mới giúp giảm bớt thời gian, thao tác bằng cách rút ngắn mã lệnh cần phải viết cho công đoạn này.

Ví dụ ta tạo một lớp SinhVien với một số thuộc tính tượng trưng theo phương pháp thông thường của C# như sau:

C# 2.0:

class Student
{
    private int id;
 
    public int ID
    {
        get { return id; }
        set { id = value; }
    }
 
    private string name;
 
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
 
    private DateTime birthDay;
 
    public DateTime BirthDay
    {
        get { return birthDay; }
        set { birthDay = value; }
    }
}
Có thể thấy là chỉ với 3 field ta đã tốn khá nhiều dòng để tạo ra các property tương ứng cho lớp SinhVien này. Bây giờ ta thử tạo lớp SinhVien với cấu trúc tương tự trong C# 3.0:

C# 3.0:

class Student
{
    public int ID { get; set; }
    public string Name { get; set; }
    public DateTime BirthDay { get; set; }
}
Một sự khác biệt đơn giản giữa hai đoạn mã của cùng một ngôn ngữ nhưng với hai phiên bản khác nhau giúp cho công việc viết mã trở nên dễ dàng hơn. Bạn có thể tiết kiệm được khá nhiều mã lệnh cần phải viết cho một lớp đồng thời giúp cho chúng dễ đọc hơn.

Trình biên dịch sẽ tự động tạo ra các biến private vô danh để lưu giữ giá trị của mỗi property này.

Trong trường hợp muốn thuộc tính chỉ cho phép đọc (read-only) bạn có thể thêm từ khóa private vào trước set ví dụ như với thuộc tính ID sau:

class Student
    {
        public int ID { get; private set; }
        public string Name { get; set; }
        public DateTime BirthDay { get; set; }
    }

2.    Khởi tạo đối tượng
(Object initializers)

Thông thường khi tạo một lớp ta phải overload một số hàm khởi tạo để sử dụng theo từng trường hợp khác nhau. Mỗi overload xác định những tham số nào cần gán cho các thuộc tính của đối tượng, công đoạn cũng khá nhàm chán và có thể phải cần đến số lượng dòng lệnh khá lớn. Để giải quyết vấn đề này, C# 3.0 cung cấp cho ta một cách viết mới cho phép gán giá trị trực tiếp cho các field hoặc property cần thiết của đối tượng được tạo chỉ trong một dòng lệnh.

Ví dụ với lớp SinhVien ở trên, bạn không tạo ra một hàm khởi tạo cụ thể nào cả và sử dụng hàm khởi tạo mặc định để tạo ra một đối tượng SinhVien với các thông tin ban đầu.

C# 2.0:

SinhVien sv = new SinhVien();
sv.MaSo = 1;
sv.HoTen = "Yin Yang";
sv.NgaySinh = new DateTime(2000, 1, 1);

Trong C# 3.0 bạn cần một dòng duy nhất để làm điều này:

C# 3.0:

Student sv = new Student{ ID = 1, Name = "Yin Yang", BirthDay = new DateTime(2000, 1, 1) };

Để mã nguồn dễ đọc, bạn có thể định dạng lại như sau:

Student sv = new Student
{
    ID = 1,
    Name = "Yin Yang",
    BirthDay = new DateTime(2000, 1, 1)
};


3.    Khởi tạo tập hợp
(Collection initializers)

Đối với khởi tạo một tập hợp và thêm vào một số phần tử, bạn có thể khởi tạo nó như một mảng. Giả sử ta cần một tập hợp có định kiểu để lưu danh sách các SinhVien.

List<Student> list = new List<Student>();

Theo cách thông thường ta phải dùng phương thức Add() để thêm từng đối tượng kiểu SinhVien vào danh sách. Trong C# 3.0 ta có thể làm điều này ngay trong lúc khởi tạo tập hợp:

List<Student> list = new List<Student>{
    new Student{ID=1,Name="Yin"},
    new Student{ID=2,Name="Yang"},
    new Student{ID=3,Name="Zen"}
};

4.    Biến cục bộ có kiểu ngầm định
(Implicitly typed local variables)

Trong C# 3.0 chúng ta có thể khai báo các biến cục bộ với kiểu không xác định thông qua từ khóa var. Khi được biên dịch, trình biên dịch sẽ tự động xác định kiểu của biến đó thông qua giá trị mà ta gán cho nó lúc khởi tạo.

Ví dụ:

var i = 100;
var s = “C# 3.0″;

Hai dòng lệnh trên tương đương với các dòng lệnh sau:

int i = 100;
string s = “C# 3.0″;

Bạn có thể gán cho biến khai báo bằng từ khóa var mọi giá trị mà bạn muốn, từ kiểu nguyên thủy, kiểu mảng cho đến những kiểu đối tượng phức tạp. Tuy nhiên cần lưu ý là, khi khai báo một biến với từ khóa var, bạn bắt buộc phải gán giá trị cho nó để trình biên dịch có thể xác định được biến đó thuộc kiểu gì. Bởi vì var không phải là một kiểu mà chỉ đơn giản là một từ khóa dùng để khai báo biến. Nếu cố làm điều này, bạn sẽ nhận được lỗi biên dịch “Implicitly-typed local variables must be initialized”. Cũng thế, việc gán null cho một biến được khai báo với var là không hợp lệ.

Vậy thì từ khóa var này có lợi ích gì? Chắc hẳn bạn sẽ tự tìm được câu trả lời sau một quá trình làm việc với nó. Trường hợp đơn giản như khi bạn khai báo một tập hợp có kiểu là List<int> và sau đó dùng foreach để duyệt qua nó, sau đó bạn lại thay đổi kiểu của tập hợp này sang List<double>. Khi đó nếu dùng var bạn không cần phải sửa kiểu biến trong cú pháp lặp nữa. Hơn nữa, mặc dù được khai báo với từ khóa var, bạn vẫn đảm bảo mã lệnh của mình được tối ưu vì không phải qua bước ép kiểu hoặc boxing nào, và vẫn sử dụng được chức năng IntelliSense của Visual Studio.

foreach (var sv in list)
{
Console.WriteLine(sv.Name+”\t”+sv.BirthDay.ToShortDateString());
}

Bạn có thể gặp một số trường hợp khác tương tự như vậy. Để thấy rõ hơn công dụng của từ khóa var, bạn hãy đọc tiếp phần sau.

5.    Kiểu dữ liệu nặc danh
(Anonymous types)

Dựa trên khái niệm “Tuple” (một bộ dữ liệu), C# 3.0 cho phép tạo ra một kiểu đối tượng tạm thời mà không cần định nghĩa trước và khai báo một lớp mới.

Cách sử dụng tương tự như việc tạo một đối tượng thông thường trong C# 3.0 ngoài việc không cần đến tên lớp. Ở đây ta sẽ thấy được vai trò không thể thiếu của từ khóa var được giới thiệu ở phần trên.

var school = new
{
ID = “DUT”,
Name = “ĐHĐN”,
Address = “Tp.ĐN”
};

Sau khi tạo ra đối tượng school này, ta có thể sử dụng nó tương tự như với các đối tượng thông thường với 3 property vừa được định nghĩa trong quá trình khởi tạo là ID, Name và Address.

Console.WriteLine(“Address: ” + school.Address);
Console.WriteLine(“Type Name: “+ school.GetType().Name);

Kết quả xuất ra như sau:

Address: Tp.ĐN
Type Name: <>f__AnonymousType0`3

Có thể thấy là trình biên dịch tự động tạo ra một class mới với tên theo quy định của nó. Trong trường hợp bạn tạo ra 2 đối tượng kiểu nặc danh với các thuộc tính giống hệt nhau, trình biên dịch cũng vẫn chỉ tạo ra duy nhất một class mới. Xem ví dụ sau để hiểu thêm điều này:

var school1 = new
{
    ID = "DUT",
    Name = "ĐHĐN",
    Address = "Tp.ĐN"
};
var school2 = new
{
    ID = "DUT",
    Name = "ĐHĐN",
    Address = "Tp.ĐN"
};
 
Console.WriteLine("Type Name: "+ school1.GetType().Name);
Console.WriteLine("Type Name: " + school2.GetType().Name);

Kết quả:

Type Name: <>f__AnonymousType0`3
Type Name: <>f__AnonymousType0`3

6.    Kết luận

Những phần được trình bày trên không phải là tất cả những điểm về cú pháp trong C# 3.0. Còn những kĩ thuật như Extension Method, Lambd Expression, Expression Tree, Partial Method,… sẽ được giới thiệu trong mỗi bài viết riêng để truyền tải được phần nào công dụng và cách thức sử dụng chúng. Tuy nhiên với những chức năng trên trong C# 3.0, chắc hẳn bạn cũng có thể nhận thấy chúng tiện lợi và hiệu quả cho công việc lập trình thế nào.

Nguồn bài viết: Sưu tầm

BÌNH LUẬN BÀI VIẾT

Bài viết mới nhất

LIKE BOX

Bài viết được xem nhiều nhất

HỌC HTML