//chúng ta đang xây dựng mô hinh ba lớp trong cơ sơ dữ liệu
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Text;
using DTO;
namespace DAO
{
public class BookDao
{
// Hàm lấy danh sách Book
public IList GetBookList()
{
// Khởi tạo đối tượng kết nối
OleDbConnection oledbCon =
DataProvider.ConnectionData();
// Khởi tạo và gán giá trị cho chuỗi truy vấn cơ sở dữ liệu
string strSQL = "Select * From Book";
// Khởi tạo đối tượng OleDBCommand thực thi câu truy vấn
OleDbCommand oledbCmd = new
OleDbCommand(strSQL, oledbCon);
// Khởi tạo đối tượng OleDBDataReader
OleDbDataReader oledbDtr =
oledbCmd.ExecuteReader();
// Khởi tạo đối tượng ArrayList
ArrayList Arl = new ArrayList();
// Khởi tạo đối tượng BookDto
BookDto BokDto = null;
// Trong khi OleDBDataReader còn có thể đọc
while(oledbDtr.Read())
{
// Khởi tạo lại đối tượng BookDto
BokDto = new BookDto();
19 trang |
Chia sẻ: tlsuongmuoi | Lượt xem: 2247 | Lượt tải: 0
Bạn đang xem nội dung tài liệu Giải thích hàm trong C, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
//chúng ta đang xây d ng mô hinh ba lop trong co so du li uự ệ
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Text;
using DTO;
namespace DAO
{
public class BookDao
{
// Hàm l y danh sách Bookấ
public IList GetBookList()
{
// Kh i t o đ i t ng k t n iở ạ ố ượ ế ố
OleDbConnection oledbCon =
DataProvider.ConnectionData();
// Kh i t o và gán giá tr cho chu i truy v n c s d li uở ạ ị ỗ ấ ơ ở ữ ệ
string strSQL = "Select * From Book";
// Kh i t o đ i t ng OleDBCommand th c thi câu truy v nở ạ ố ượ ự ấ
OleDbCommand oledbCmd = new
OleDbCommand(strSQL, oledbCon);
// Kh i t o đ i t ng OleDBDataReaderở ạ ố ượ
OleDbDataReader oledbDtr =
oledbCmd.ExecuteReader();
// Kh i t o đ i t ng ArrayListở ạ ố ượ
ArrayList Arl = new ArrayList();
// Kh i t o đ i t ng BookDtoở ạ ố ượ
BookDto BokDto = null;
// Trong khi OleDBDataReader còn có th đ cể ọ
while(oledbDtr.Read())
{
// Kh i t o l i đ i t ng BookDtoở ạ ạ ố ượ
BokDto = new BookDto();
// Gán giá tr cho các tr ng c a BookDtoị ườ ủ
// Gán giá tr cho BookIDị
BokDto.ID = (string)oledbDtr["BookID"];
// Gán giá tr cho BookNameị
BokDto.Name =
(string)oledbDtr["BookName"];
// Gán giá tr cho BookDateOfPuslishị
BokDto.DateOfPuslish =
(string)oledbDtr["BookDateOfPuslish"];
// Gán giá tr cho BookPriceị
BokDto.Price =
(string)oledbDtr["BookPrice"];
// Gán giá tr cho BookStatusị
BokDto.Status =
(string)oledbDtr["BookStatus"];
// Gán giá tr cho BookAmountị
BokDto.Amount = (string)oledbDtr["BookAmount"];
// Gán giá tr cho BookRemainị
BokDto.Remain = (string)oledbDtr["BookRemain"];
// Gán giá tr cho BookDecriptionị
BokDto.Decription =
(string)oledbDtr["BookDecription"];
// Gán giá tr cho BookAuthorIDị
BokDto.AuthorID =
(string)oledbDtr["BookAuthorID"];
// Gán giá tr cho BookCategoryIDị
BokDto.CategoryID =
(string)oledbDtr["BookCategoryID"];
// Thêm đ i t ng BookDto v a t o vào ArrayListố ượ ừ ạ
Arl.Add(BokDto);
}
// Đóng k t n i OleDBConnectionế ố
oledbCon.Close();
// Đóng k t n i OleDBDataReaderế ố
oledbDtr.Close();
// Tr v đ i t ng ArrayListả ề ố ượ
return Arl;
}
// Hàm l y m t đ i t ng BookDto t c s d li u khi bi tấ ộ ố ượ ừ ơ ở ữ ệ ế
BookID
public BookDto GetBook(string stringBookID)
{
// Kh i t o đ i t ng k t n iở ạ ố ượ ế ố
OleDbConnection oledbCon = DataProvider.ConnectionData();
// Kh i t o và gán giá tr cho chu i truy v n c s d li uở ạ ị ỗ ấ ơ ở ữ ệ
string strSQL = "Select * From Book Where BookID = ?";
// Kh i t o đ i t ng OleDBCommand th c thi v i tham s làở ạ ố ượ ự ớ ố
chu i truy v n và đ i t ng k t n iỗ ấ ố ượ ế ố
OleDbCommand oledbCmd = new OleDbCommand(strSQL,
oledbCon);
// Gán tham s cho các tr ngố ườ
// Gán tham s cho AuthorIDố
oledbCmd.Parameters.Add("@BookID", OleDbType.WChar);
oledbCmd.Parameters["@BookID"].Value = stringBookID;
// Kh i t o đ i t ng OleDBDataReader th c thi có truy v n câuở ạ ố ượ ự ấ
l nhệ
OleDbDataReader oledbDtr = oledbCmd.ExecuteReader();
// Kh i t o đ i t ng AuthorDtoở ạ ố ượ
BookDto bookDto = new BookDto();
// Trong khi đ i t ng OleDBDataReader còn có th đ cố ượ ể ọ
while (oledbDtr.Read())
{
// Gán giá tr cho đ i t ng BookDtoị ố ượ
// Gán giá tr cho BookIDị
bookDto.ID = (string)oledbDtr["BookID"];
// Gán giá tr cho BookNameị
bookDto.Name = (string)oledbDtr["BookName"];
// Gán giá tr cho BookDateOfPuslishị
bookDto.DateOfPuslish =
(string)oledbDtr["BookDateOfPuslish"];
// Gán giá tr cho BookPriceị
bookDto.Price = (string)oledbDtr["BookPrice"];
// Gán giá tr cho BookStatusị
bookDto.Status = (string)oledbDtr["BookStatus"];
// Gán giá tr cho BookAmountị
bookDto.Amount = (string)oledbDtr["BookAmount"];
// Gán giá tr cho BookRemainị
bookDto.Remain = (string)oledbDtr["BookRemain"];
// Gán giá tr cho BookDecriptionị
bookDto.Decription = (string)oledbDtr["BookDecription"];
// Gán giá tr cho BookAuthorIDị
bookDto.AuthorID = (string)oledbDtr["BookAuthorID"];
// Gán giá tr cho BookCategoryIDị
bookDto.CategoryID = (string)oledbDtr["BookCategoryID"];
}
// Đóng k t n iế ố
oledbCon.Close();
// Tr v đ i t ng AuthorDtoả ề ố ượ
return bookDto;
}
// Hàm thêm Book v i tham s là BookDtoớ ố
public void AddBook(BookDto bookDto)
{
// Kh i t o đ i t ng k t n iở ạ ố ượ ế ố
OleDbConnection oledbCon = DataProvider.ConnectionData();
// Kh i t o và gán giá tr cho chu i truy v n c s d li uở ạ ị ỗ ấ ơ ở ữ ệ
string strSQL = "Insert Into Book( BookID, BookName,
BookDateOfPuslish, BookPrice, BookStatus, BookAmount,
BookRemain, BookDecription, BookAuthorID, BookCategoryID)
Values( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// Kh i t o đ i t ng OleDBCommand v i tham s là chu i truyở ạ ố ượ ớ ố ỗ
v n và đ i t ng k t n iấ ố ượ ế ố
OleDbCommand oledbCmd = new OleDbCommand(strSQL,
oledbCon);
// Gán tham s cho các tr ngố ườ
// Gán tham s cho BookIDố
oledbCmd.Parameters.Add("@BookID", OleDbType.WChar);
oledbCmd.Parameters["@BookID"].Value = bookDto.ID;
// Gán tham s cho BookNameố
oledbCmd.Parameters.Add("@BookName", OleDbType.WChar);
oledbCmd.Parameters["@BookName"].Value = bookDto.Name;
// Gán tham s cho BookDateOfPuslishố
oledbCmd.Parameters.Add("@BookDateOfPuslish",
OleDbType.WChar);
oledbCmd.Parameters["@BookDateOfPuslish"].Value =
bookDto.DateOfPuslish;
// Gán tham s cho BookPriceố
oledbCmd.Parameters.Add("@BookPrice", OleDbType.WChar);
oledbCmd.Parameters["@BookPrice"].Value = bookDto.Price;
// Gán tham s cho BookStatusố
oledbCmd.Parameters.Add("@BookStatus", OleDbType.WChar);
oledbCmd.Parameters["@BookStatus"].Value = bookDto.Status;
// Gán tham s cho BookAmountố
oledbCmd.Parameters.Add("@BookAmount",
OleDbType.WChar);
oledbCmd.Parameters["@BookAmount"].Value =
bookDto.Amount;
// Gán tham s cho BookRemainố
oledbCmd.Parameters.Add("@BookRemain",
OleDbType.WChar);
oledbCmd.Parameters["@BookRemain"].Value =
bookDto.Remain;
// Gán tham s cho BookDecriptionố
oledbCmd.Parameters.Add("@BookDecription",
OleDbType.WChar);
oledbCmd.Parameters["@BookDecription"].Value =
bookDto.Decription;
// Gán tham s cho BookAuthorIDố
oledbCmd.Parameters.Add("@BookAuthorID",
OleDbType.WChar);
oledbCmd.Parameters["@BookAuthorID"].Value =
bookDto.AuthorID;
// Gán tham s cho BookCategoryIDố
oledbCmd.Parameters.Add("@BookCategoryID",
OleDbType.WChar);
oledbCmd.Parameters["@BookCategoryID"].Value =
bookDto.CategoryID;
// Th c thi không truy v n c s d li u b ng đ i t ngự ấ ơ ở ữ ệ ằ ố ượ
OleDBCommand
oledbCmd.ExecuteNonQuery();
// Đóng k t n iế ố
oledbCon.Close();
}
// Hàm xóa m t Book khi bi t BookIDộ ế
public void DeleteBook(string stringBookID)
{
// Kh i t o đ i t ng k t n iở ạ ố ượ ế ố
OleDbConnection oledbConnection =
DataProvider.ConnectionData();
// Kh i t o và gán giá tr cho chu i truy v n c s d li uở ạ ị ỗ ấ ơ ở ữ ệ
string stringSql = "Delete * From Book Where BookID = ?";
// Kh i t o đ i t ng OleDBCommandở ạ ố ượ
OleDbCommand oledbCommand = new
OleDbCommand(stringSql, oledbConnection);
// Gán tham sô cho các tr ngườ
oledbCommand.Parameters.Add("@BookID",
OleDbType.WChar);
oledbCommand.Parameters["@BookID"].Value = stringBookID;
// Th c thi không truy v n c s d li uự ấ ơ ở ữ ệ
oledbCommand.ExecuteNonQuery();
// Đóng k t n iế ố
oledbConnection.Close();
}
// Hàm c p nh t thông tin Bookậ ậ
public void UpdateBook(BookDto bookDto)
{
// Kh i t o đ i t ng k t n i c s d li uở ạ ố ượ ế ố ơ ở ữ ệ
OleDbConnection oledbConnection =
DataProvider.ConnectionData();
// Kh i t o và gán giá tr cho chu i truy v n c s d li uở ạ ị ỗ ấ ơ ở ữ ệ
string stringSql = "Update Book Set BookName = ?,
BookDateOfPuslish = ?, BookPrice = ?, BookStatus = ?, BookAmount
= ?, BookRemain = ?, BookDecription = ?, BookAuthorID = ?,
BookCategoryID = ? Where BookID = ?";
// Kh i t o đ i t ng OleDBCommandở ạ ố ượ
OleDbCommand oledbCommand = new
OleDbCommand(stringSql, oledbConnection);
// Gán tham s cho các giá trố ị
// Gán tham s cho BookNameố
oledbCommand.Parameters.Add("@BookName",
OleDbType.WChar);
oledbCommand.Parameters["@BookName"].Value =
bookDto.Name;
// Gán tham s cho BookDateOfPuslishố
oledbCommand.Parameters.Add("@BookDateOfPuslish",
OleDbType.WChar);
oledbCommand.Parameters["@BookDateOfPuslish"].Value =
bookDto.DateOfPuslish;
// Gán tham s cho BookPriceố
oledbCommand.Parameters.Add("@BookPrice",
OleDbType.WChar);
oledbCommand.Parameters["@BookPrice"].Value =
bookDto.Price;
// Gán tham s cho BookStatusố
oledbCommand.Parameters.Add("@BookStatus",
OleDbType.WChar);
oledbCommand.Parameters["@BookStatus"].Value =
bookDto.Status;
// Gán tham s cho BookAmountố
oledbCommand.Parameters.Add("@BookAmount",
OleDbType.WChar);
oledbCommand.Parameters["@BookAmount"].Value =
bookDto.Amount;
// Gán tham s cho BookRemainố
oledbCommand.Parameters.Add("@BookRemain",
OleDbType.WChar);
oledbCommand.Parameters["@BookRemain"].Value =
bookDto.Remain;
// Gán tham s cho BookDecriptionố
oledbCommand.Parameters.Add("@BookDecription",
OleDbType.WChar);
oledbCommand.Parameters["@BookDecription"].Value =
bookDto.Decription;
// Gán tham s cho BookAuthorIDố
oledbCommand.Parameters.Add("@BookAuthorID",
OleDbType.WChar);
oledbCommand.Parameters["@BookAuthorID"].Value =
bookDto.AuthorID;
// Gán tham s cho BookCategoryIDố
oledbCommand.Parameters.Add("@BookCategoryID",
OleDbType.WChar);
oledbCommand.Parameters["@BookCategoryID"].Value =
bookDto.CategoryID;
// Gán tham s cho BookIDố
oledbCommand.Parameters.Add("@BookID",
OleDbType.WChar);
oledbCommand.Parameters["@BookID"].Value = bookDto.ID;
// Th c thi chu i truy v n c s d li uự ỗ ấ ơ ở ữ ệ
oledbCommand.ExecuteNonQuery();
// Đóng k t n iế ố
oledbConnection.Close();
sqlconnection.Open()//mo chuoi ket noi
}
}
}
K thu t l p trình 3.0 v i C#ỹ ậ ậ ớ
Ng i l p trình đã d dàng ti p c n v i l p trình FP do nhi u k thu tườ ậ ễ ế ậ ớ ậ ề ỹ ậ
trong C# 3.0 có đi m chung v i FP. Đ i v i ng i l p trình OOP, c mể ớ ố ớ ườ ậ ả
nh n đ u tiên khi làm vi c v i C# 3.0 là s thay đ i v cú pháp l pậ ầ ệ ớ ự ổ ề ậ
trình v i các k thu t nh Anonymous type, Lambda Expression hayớ ỹ ậ ư
Lazy evaluation. K t h p các k thu t này l i v i nhau s gi m thi uế ợ ỹ ậ ạ ớ ẽ ả ể
s l ng công vi c và áp l c công vi c cho ng i l p trình, đ ng th iố ượ ệ ự ệ ườ ậ ồ ờ
làm tăng tính hi u qu c a s n ph m do code nh , g n,ệ ả ủ ả ẩ ỏ ọ
Type Inference – Anonymous type:
Type Inference: Đ c dùng đ khai báo bi n v i t khóa “var” màượ ể ế ớ ừ
không c n đ nh nghĩa ki u d li u. Trình biên d ch s t đ ng suy lu nầ ị ể ữ ệ ị ẽ ự ộ ậ
ki u b ng cách tham chi u đ n giá tr đ c gán cho bi n. Tuy nhiênể ằ ế ế ị ượ ế
ki u khai báo này ch đ c s d ng trong ph m vi local.ể ỉ ượ ử ụ ạ
var Name =”An”;
var Age = “1/1/1980”;
var Numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Anonymous type: đ c xây d ng trên khái ni m “Tuple” - t p m t dãyượ ự ệ ậ ộ
d li u. Thí d d i đây có 3 Tuple.ữ ệ ụ ướ
Name:An
salary:300
City: Ho Chi Minh
Anonymous type dùng đ đ nh nghĩa m t ki u d li u m i nh ngể ị ộ ể ữ ệ ớ ư
không c n ch rõ tên và c u trúc d li u.ầ ỉ ấ ữ ệ
var myInfo = new {Name =”An”, Age=”1/1/1980”, Salary=300};
var mySalary = myInfo.Salary * 2;
Bi n myInfo đ c kh i t o v i m t ki u d li u hoàn toàn m i nh ngế ượ ở ạ ớ ộ ể ữ ệ ớ ư
không đ nh nghĩa c u trúc rõ ràng. Phép toán “var mySalary =ị ấ
myInfo.Salary*2” không gây ra l i b i trình biên d ch hi u rõ c u trúcỗ ở ị ể ấ
ki u d li u c a myInfo. M t trong nh ng u đi m c a Anonymousể ữ ệ ủ ộ ữ ư ể ủ
type là k t h p v i Type Inference trong vi c tham chi u d li u.ế ợ ớ ệ ế ữ ệ
ng d ng Type Inference – Anonymous type trong vi c tham chi u dỨ ụ ệ ế ữ
li u: các d án ít hay nhi u đ u liên quan đ n t ng tác v i d li u vàệ ự ề ề ế ươ ớ ữ ệ
ng i l p trình ph i vi t nh ng đo n mã đ l c m t t p d li u m iườ ậ ả ế ữ ạ ể ọ ộ ậ ữ ệ ớ
t t p d li u ban đ u. T p d li u m i có th ít field h n hay có thừ ậ ữ ệ ầ ậ ữ ệ ớ ể ơ ể
k t h p v i t p d li u khác nhi u field h n. Công vi c này đ c g iế ợ ớ ậ ữ ệ ề ơ ệ ượ ọ
là tham chi u hay “Projection”. Tr c đây công vi c này th ng t nế ướ ệ ườ ố
khá nhi u th i gian do ph i đ nh nghĩa c u trúc d li u, vi t mã l u dề ờ ả ị ấ ữ ệ ế ư ữ
li u vào c u trúc m i ... mà đôi khi c u trúc d li u m i ch s d ngệ ấ ớ ấ ữ ệ ớ ỉ ử ụ
trong m t hàm. Amonumous type tr nên r t hi u qu trong nh ng yêuộ ở ấ ệ ả ữ
c u nh th . V i t p d li u thí d 4, yêu c u t o m t danh sáchầ ư ế ớ ậ ữ ệ ở ụ ầ ạ ộ
nh ng ng i tên “Huy” và danh sách m i này v i ch l y hai field Nameữ ườ ớ ớ ỉ ấ
và Salary và thêm m t field m i Allowance có th x lý nh sau:ộ ớ ể ử ư
Thí d 8:ụ
var searchList = from r in people
where r.Name == “Huy”
select new { r.Name, r.Salary, Allowance = r.Salary * 0.7 };
Ki u d li u m i “searchList” v i 3 field “Name, Salary, Allowance”ể ữ ệ ớ ớ
đ c t o mà không c n đòi h i quá nhi u th i gian cho vi c đ nh nghĩaượ ạ ầ ỏ ề ờ ệ ị
c u trúc, vi t code hay phát hi n l i. Tuy nhiên “Anonymous type” chấ ế ệ ỗ ỉ
s d ng trong pham vi local.ử ụ
Lambda Expression: Anonymous method h tr cách vi t inline codeỗ ợ ế
nh ng ch a có s thay đ i đáng k v cú pháp câu l nh. Lambdaư ư ự ổ ể ề ệ
Expression là s phát tri n c a Anonymous method, giúp gi i quy tự ể ủ ả ế
gánh n ng c a ng i l p trình trong vi c vi t các đo n mã. Có thặ ủ ườ ậ ệ ế ạ ể
hi u Lambda Expression nh m t hàm mang các bi n s . Cú pháp “x =>ể ư ộ ế ố
x+1” gi ng nh hàm có m t bi n “x” và giá tr tr v c a hàm là “x+1”.ố ư ộ ế ị ả ề ủ
Lambda Expression đ c xây d ng trên n n c a lý thuy t “Lambdaượ ự ề ủ ế
calculus” đ c phát minh trong th p niên 1930. Kí t Lambda (?) c aượ ậ ự ủ
ng i Hy L p đ c dùng đ t phía tr c các bi n s c a hàm. Thí dườ ạ ượ ặ ướ ế ố ủ ụ
d i đây bi u di n hàm m t bi n và hàm hai bi n b ng Lambdaướ ể ễ ộ ế ế ằ
Expression và cú pháp trong ngôn ng C# 3.0.ữ
f(x) = x f(x,y) = x + y
Lambda Expression x ? x (x,y) ? x + y
C# 3.0 x => x (x,y) => x + y
Nh vào cú pháp đ n gi n, nên dòng l nh cũng đ n gi n.ờ ơ ả ệ ơ ả
Thí du 9:
Func Add = (x, y) => x + y;
Lambda Expression có th không có m t tham s (parameter) nào ho cể ộ ố ặ
có nhi u parameter và các parameter này cũng có th đ c khai báoề ể ượ
ki u ho c không c n khai báo ki u.ể ặ ầ ể
n => (n-1)*(n-2)
x => (x % 2) == 0
(int x) => (x % 2) == 0
p => p.Name == “Huy” && p.Age > 25
Các k thu t Closure hay Currying đ u có th s d ng trong Lambdaỹ ậ ề ể ử ụ
Expression.
Closure trong Lambda Expression là kh năng hi u và ki m soát bi nả ể ể ế
không n m trong ph m vi c a bi u th c.ằ ạ ủ ể ứ
Thí d 10:ụ
int x = 99;
Func add = y => y + x;
int firstResult = add(1); // 99 + 1 = 100
int secondResult = add(2); // 99 + 2 = 101
Tuy “y” không là bi n local và nó cũng không là parameter c a methodế ủ
nh ng ch ng trình không báo l i và nó đ c xem nh là m t bi n “tư ươ ỗ ượ ư ộ ế ự
do”. K t qu c a bi u th c firstResult là 100 và trong tr ng h p nàyế ả ủ ể ứ ườ ợ
Closure có vai trò l u tr ng thái giá tr m t bi n đ có th s d ng l iư ạ ị ộ ế ể ể ử ụ ạ
sau.
Currying trong Lambda Expression cho hàm f(x,y):
static Func f(int x)
{ Func add = (y, z) => y + z;
return y => add(x, y);
}
var Currying = f(1);
int three = Currying(2); // = 1 + 2
int four = Currying(3); // = 1 + 3
Th t khó đ th y ng d ng c a Currying vào th c t . Tuy nhiên nó cóậ ể ấ ứ ụ ủ ự ế
th thích h p trong khoa h c máy tính cho vi c chia nh các hàm toánể ợ ọ ệ ỏ
h c có n bi n ch a các phép toán ph c t p thành n-1 hàm đ n gi n h n.ọ ế ứ ứ ạ ơ ả ơ
Query Expression: Đây là s h tr ngôn ng LINQ cho C# 3.0 trongự ỗ ợ ữ
vi c xây d ng nh ng câu truy v n inline. Ngoài nh ng câu l nh trôngệ ự ữ ấ ữ ệ
gi ng nh ngôn ng SQL “Select”, “From”, “Where” (thí d 8) thì vi cố ư ữ ụ ệ
ng d ng “Lambda Expression” vào trong “Query Expression” s làmứ ụ ẽ
đ n gi n đi công vi c truy v n d li u. Các câu l nh truy v n tr nênơ ả ệ ấ ữ ệ ệ ấ ở
ng n g n và d hi u.ắ ọ ễ ể
Thí d 8 đ c vi t l i b ng “Lambda Expression”:ụ ượ ế ạ ằ
Thí d 11:ụ
var searchList = people
.Where(p => p.Name == “Huy”)
.Select(p => new { p.Name, p.Salary, allowance = p.Salary * 0.7 });
M t thí d tìm tu i l n nh t trong danh sách, n u tr c đây ng i l pộ ụ ổ ớ ấ ế ướ ườ ậ
trình ph i vi t m t stored procedure hay m t đo n mã so sánh các ph nả ế ộ ộ ạ ầ
t trong danh sách thì v i C# 3.0 ch c n m t l nh:ử ớ ỉ ầ ộ ệ
int maxAge = people.Max(p => p.Age);
M t k thu t r t h u ích trong Query Expression là ộ ỹ ậ ấ ữ Extension Method.
Tr c đây, đ i v i các class thu c hãng th ba hay nh ng class vì lý doướ ố ớ ộ ứ ữ
nào đó đ c khai báo đóng kín, ng i l p trình th ng g p nhi u khóượ ườ ậ ườ ặ ề
khăn do không đ c phép thay đ i hay thêm nh ng method cho phù h pượ ổ ữ ợ
v i yêu c u m i. Thí d class Integer c a C#, ng i l p trình không thớ ầ ớ ụ ủ ườ ậ ể
thêm method Square nh l nh g i d i đây:ư ệ ọ ướ
Thí d 12:ụ
int myValue = 2;
myValue.Square();
Class Integer c a C# hoàn toàn không có method Square. Nh k thu tủ ờ ỹ ậ
Extention Method, ng i l p trình có th làm vi c v i nh ng yêu c uườ ậ ể ệ ớ ữ ầ
nh th . Gi s class ListPerson ch cung c p duy nh t hàm tìm ki mư ế ả ử ỉ ấ ấ ế
theo tên và không th th a k hay thêm m i vào class này. N u có m tể ừ ế ớ ế ộ
yêu c u tìm ki m theo tu i thì ng i l p trình không th t gi i quy tầ ế ổ ườ ậ ể ự ả ế
v n đ . Dùng k thu t Extention Method đ nh nghĩa m t class m iấ ề ỹ ậ ị ộ ớ
d ng static và bên trong class này đ nh nghĩa m t static method v i tạ ị ộ ớ ừ
khóa this cho bi n s đ u tiên c a method. Method Square đ c đ nhế ố ầ ủ ượ ị
nghĩa:
public static int Square(this int myNumber)
{ return myNumber * myNumber; }
Tr l i yêu c u tìm ki m theo tu i trong danh sách, t o m t methodở ạ ầ ế ổ ạ ộ
m i tên MyQuery:ớ
namespace MyExtentionMethod
{ delegate R Func(T t);
static class PersonExtensions
{ public static IEnumerable MyQuery(this IEnumerable
sequence, Func predicate)
{ foreach (T item in sequence)
if (predicate(item))
yield return item; }
}
}
Tìm nh ng nhân viên có tu i l n h n 29 hay có l ng l n h n 400:ữ ổ ớ ơ ươ ớ ơ
ListPerson person = new ListPerson(people);
var myListAge = person.MyQuery(p => p.Age > 29);
var myListSalary = person.MyQuery(p => p.Salary > 400 );
Trông có v nh method MyQuery thu c vào class ListPersonẻ ư ộ
(person.MyQuery) h n là class m i đ nh nghĩa PersonExtensions.ơ ớ ị
Lazy evaluation: Đây là k thu t r t đ c các ngôn ng l p trình quanỹ ậ ấ ượ ữ ậ
tâm, nh ng Lazy evaluation trong C# 3.0 t nhiên và đ n gi n h n. Giư ự ơ ả ơ ả
s f(x,y) = x+y ch x y ra khi th a đi u ki n x >= 0 và y >= 0:ử ỉ ả ỏ ề ệ
Thí d 13:ụ
static Func Add = (x, y) => x + y;
static int MyLazyEvaluation(int x, int y, int function)
{ if (x <= 0 || y <= 0) return 0; else return function;}
int value = MyLazyEvaluation(-1, 2, Add(-1, 2));
Hàm MyLazyEvaluation đu c truy n giá tr “-1” cho tham s x, cho nênợ ề ị ố
ch ng trình s không thi hành hàm Add(-1,2).ươ ẽ
T khóa yield trong vòng l p cũng là Lazy evaluation. Có th ki m traừ ặ ể ể
tính Lazy evaluation c a t khóa yield b ng đo n mã trong danh sáchủ ừ ằ ạ
d i đây:ướ
static IEnumerable Print(this IEnumerable person)
{ foreach (Person p in person)
{ Console.WriteLine(index.ToString()+”: Person: {0}”, p.Name);
index += 1;
p.Name = p.Name.ToUpper();
yield return p; }
}
Đo n mã ki m tra tính Lazy valuation c a thí d trên:ạ ể ủ ụ
Console.WriteLine(“Before using ToUpper()”);
var printPerson = people.Print();
Console.WriteLine(“After using ToUpper()”);
foreach (Person pp in printPerson)
Console.WriteLine(“-- After Upper: {0}”, pp.Name);
K t qu trên màn hình:ế ả
Before using ToUpper()
After using ToUpper()
1: Customer: An
After Upper: AN
2: Customer: Dung
After Upper: DUNG
......
Thí d trên cho th y vòng l p “foreach (Person p in person)” trong hàmụ ấ ặ
Print hoàn toàn không thi hành liên t c dòng l nh ToUpper() v i t khoáụ ệ ớ ừ
yield. L nh ToUpper() m t person ti p theo ch đ c g i khi nó th t sệ ộ ế ỉ ượ ọ ậ ự
đ c yêu c u. Trong tr ng h p này là dòng l nh “foreach (Person ppượ ầ ườ ợ ệ
in printPerson)” c a đo n mã ki m tra k t qu Lazy valuation.ủ ạ ể ế ả
Higher Order Function: Tuy là m t k thu t r t c b n trong l p trìnhộ ỹ ậ ấ ơ ả ậ
FP nh ng nó ch m i xu t hi n t C# 2.0. Higher Order Function xemư ỉ ớ ấ ệ ừ
hàm cũng là d ng d li u cho nên parameter c a hàm cũng là m t hàm.ạ ữ ệ ủ ộ
Trong các thí d trên, có m t s ng d ng Higher Order Function nhụ ộ ố ứ ụ ư
thí d 4, parameter c a method FindAll là hàm SearchNameụ ủ
(people.FindAll(SearchName)). Thí d 10, parameter “function” trongụ
hàm MyLazyEvaluation(int x, int y, int function) có ki u là integer,ể
nh ng nó l i đ c truy n vào là m t hàm Add(-1, 2)ư ạ ượ ề ộ
(“MyLazyEvaluation(-1, 2, Add(-1, 2))”) .
“Filter”, “Map” và “Reduce” đ c xem là ba Higher Order Function r tượ ấ
h u ích cho các phép toán trong dãy (List, Aray, IEnumerable). Tuyữ
nhiên Higher Order Function trong C# 2.0 ch h tr cho ki u d li uỉ ỗ ợ ể ữ ệ
List và Array.
Filter: Các method FindAll hay RemoveAll đ c xem là các Filter vàượ
parameter c a các hàm này là m t hàm đi u ki n mà m t khi các ph nủ ộ ề ệ ộ ầ
t trong dãy th a đi u ki n c a hàm thì các ph n t này s đ c ch nử ỏ ề ệ ủ ầ ử ẽ ượ ọ
(Find) hay b xóa (Remove) kh i danh sách. Thí d tìm ki m danh sáchị ỏ ụ ế
nh ng ng i tên “An”:ữ ườ
people.FindAll(delegate(Person p) { return p.Name.Equals(“An”); })
Tuy nhiên, n u mu n tìm m t danh sách nh ng ng i tên “Huy”, ng iế ố ộ ữ ườ ườ
l p trình l i ph i vi t thêm m t Anonymous Delegate t ng t nhậ ạ ả ế ộ ươ ự ư
th . Đ tránh tr ng h p này, s d ng Higher Order Function b ngế ể ườ ợ ử ụ ằ
cách đ nh nghĩa hàm SearchName:ị
public static Predicate SearchName(string name)
{ return delegate(Person p) { return p.Name.Equals(name); }; }
......
var AnList = people.FindAll(SearchName(“An”));
var HuyList = people.FindAll(SearchName(“Huy”));
Cách vi t trong C# 3.0 ng n g n h n:ế ắ ọ ơ
var AnList = people.FindAll(p => p.Name.Equals(“An”));
hay
var person = people.Where(p=>p.Name.Equals(“An”));
Nh v y “Filter” trong C# 2.0 t ng đ ng v i “Where” trong C# 3.0.ư ậ ươ ồ ớ
Map: Dùng đ t o ra m t dãy m i t m t dãy ban đ u theo m t phépể ạ ộ ớ ừ ộ ầ ộ
toán t ng ng. Hàm ConvertAll() là m t “Map”. Parameter c a hàmươ ứ ộ ủ
này cũng là m t hàm s nh h ng lên t ng ph n t c a dãy. Câu l nhộ ẽ ả ưở ừ ầ ử ủ ệ
t o m t danh sách m i v i m c l ng nhân v i h s “0.7”:ạ ộ ớ ớ ứ ươ ớ ệ ố
var allowanceSalary = people.ConvertAll(delegate(Person p)
{ return p.Salary *= 0.7; });
vi t l i v i C# 3.0:ế ạ ớ
var allowanceSalary = people.ConvertAll(p => p.Salary * 0.7);
hay
var allowanceSalary = people.Select(p => p.Salary * 0.7);
Nh v y “Map” trong C# 2.0 t ng đ ng v i “Select” trong C# 3.0.ư ậ ươ ồ ớ
Reduce: Còn đ c hi u nh là “Fold” trong l p trình FP. Đây là khượ ể ư ậ ả
năng tính toán giá tr c a dãy b ng cách l t qua t t c các ph n tị ủ ằ ướ ấ ả ầ ử
trong dãy. Tính t ng ti n l ng trong danh sách:ổ ề ươ
int total = people.Aggregate(0,
delegate(int currentSum, Person p)
{ return currentSum + p.Salary; });
C# 3.0:
var total = people.Select(p => p.Salary).Aggregate(0, (x, y) => x + y);
.NET Framework 3.5 cung c p m t s hàm tính toán cho dãy nh Sum,ấ ộ ố ư
Average, Count, Min, Max. Do đó có th th y r ng Filter hay Map trongể ấ ằ
C# 2.0 không còn thích h p cho C# 3.0 b i vì Lambda Expression đãợ ở
hoàn toàn có th thay th và LINQ đang ngày càng ph bi n. Thí dể ế ổ ế ụ
tính t ng s l ng c a nh ng ng i có tu i l n h n 29:ổ ố ươ ủ ữ ườ ổ ớ ơ
var total = people.Where(p => p.Age>29).Select(p => p.Salary).Sum();
hay
var total = (from p in people where (p.Age > 29) select p.Salary).Sum();
K T LU NẾ Ậ
L p trình FP trong .Net tuy còn h n ch , nh ng ti p c n v i k thu tậ ạ ế ư ế ậ ớ ỹ ậ
này s giúp ng i l p trình ti t ki m r t nhi u th i gian trong vi c vi tẽ ườ ậ ế ệ ấ ề ờ ệ ế
và qu n lý code cũng nh phát hi n l i, đ ng nghĩa v i ti t ki m chiả ư ệ ỗ ồ ớ ế ệ
phí và nhân s cho d án. Và h n n a, FP cho phép khai thác s c m nhự ự ơ ữ ứ ạ
c a các b x lý đa nhân.ủ ộ ử
Các file đính kèm theo tài liệu này:
- Giải thích hàm trong c.pdf