Tải bản đầy đủ (.pdf) (22 trang)

Tuan03 c net basic p2

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (858.08 KB, 22 trang )

9/18/2018

Lập trình Ứng dụng quản lý
C#.NET cơ bản
phần tiếp theo

Nội dung
 Một vài C# keyword
 Collections
 Generics
 Delegates

1


9/18/2018

Nội dung
 Một vài C# keyword
 Collections
 Generics
 Delegates

C# keyword: partial
 Giúp chia class thành nhiều phần cài đặt.

File: SinhVien.Internal.cs
partial class SinhVien
{
public string MSSV { get; set; }
public string HoTen { get; set; }


public string QueQuan { get; set; }
public float DiemToan { get; set; }
public float DiemAnhVan { get; set; }
public float DiemTrietHoc { get; set; }
}
File: SinhVien.cs
partial class SinhVien
{
public float GetDiemTrungBinh()
{
return (DiemToan + DiemAnhVan + DiemTrietHoc) / 3;
}
}

2


9/18/2018

C# keyword: as
 Chuyển đổi kiểu thực sự được thực hiện khi

runtime, không phải khi compile.
object o = new CTest();
Square s = (Square)o;

 Sử dụng as
object o = new CTest();
var s = o as Square;
if (s != null)

{
//...
}

error??? nếu o khơng
thật sự là Square

nếu o khơng thật sự là
Square thì kết quả trả về là
null

C# keyword: is
 Sử dụng trong trường hợp thể hiện trong cây kế

thừa.

class Shape
{ }
class Shape2D : Shape
{
public string Name { get; set; }
}
class Square : Shape2D
{
public int Side { get; set; }
}

object o = new Square();
if (o is Shape2D)
{

((Shape2D)o).Name = "A";
}
if (o is Square)
{
((Square)o).Side = 5;
}

3


9/18/2018

Nội dung
 Một vài C# keyword
 Collections
 Generics
 Delegates

Collections
 Collection là kiểu dữ liệu lưu trữ tập các dữ liệu

(set of data).
 Trong .NET cung cấp 2 loại collection
 Nongeneric collections (namespace

System.Collections).
 Generic collections (namespace
System.Collections.Generic)

4



9/18/2018

ArrayList
 Kiểu dữ liệu phần tử (item) là object.
ArrayList strArray = new ArrayList();
strArray.AddRange(new string[] { "First", "Second", "Third" });
Console.WriteLine("This collection has {0} items.", strArray.Count);
Console.WriteLine();
strArray.Add("Fourth!");
Console.WriteLine("This collection has {0} items.", strArray.Count);
foreach (string s in strArray)
{
Console.WriteLine("Entry: {0}", s);
}
Console.WriteLine();

Vấn đề nongeneric
 Kiểm soát kiểu dữ liệu khó khăn.
 Hiệu năng kém khi phải chuyển đổi kiểu dữ liệu

nhiều lần giữa value type và reference type
(boxing, unboxing)
ArrayList al = new ArrayList();
al.Add(10);
al.Add("10");
al.Add(new CTest());
foreach (int i in al)
{

Console.WriteLine(i);
}

error???
vì phần tử khơng thật
sự tất cả là int

5


9/18/2018

Nội dung
 Một vài C# keyword
 Collections
 Generics
 Delegates

Generics
 Generic nghĩa là “tổng quát” hàm ý đưa ra những cách làm

chung nhất cho nhiều vấn đề.
 Tình huống ví dụ cần xây dựng 1 Ngăn xếp (Stack) chứa kiểu

dữ liệu int với các phương thức cơ bản như: push, pop,
check,… Sau đó lại cần xây dựng cũng Stack với các phương
thức như vậy nhưng dữ liệu lại là string
 Giải pháp cho vấn đề trên?
public class IntStack
{

int[] _data = new int[100];
int _curIdx = -1;
public void Push(int value)
{
_data[++_curIdx] = value;
}
public int Pop()
{
return _data[_curIdx--];
}
}

6


9/18/2018

Giải pháp
 Cách đầu tiên thường làm: copy lại và thay đổi kiểu

dữ liệu trong code. Nếu có yêu cầu đổi kiểu dữ liệu
sang float, double,…???
 Cách tốt hơn khi đã biết đến kiểu dữ liệu cơ sở trong
.NET là object. Khi sử dụng kiểu dữ liệu object thì
Stack đã chấp nhận được mọi kiểu dữ liệu?
public class ObjectStack
{
object[] _data = new object[100];
int _curIdx = -1;
public void Push(object value)

{
_data[++_curIdx] = value;
}
public object Pop()
{
return _data[_curIdx--];
}
}

Vấn đề
 Vấn đề của ObjectStack kể trên là dễ gây ra lỗi

runtime (tức là chỉ giải quyết tốt về mặt syntax)
ObjectStack s = new ObjectStack();
//push vào kiểu string
s.Push("test");
//lấy ra lại kiểu int
int i = (int)s.Pop();

 .NET cung cấp giải pháp cho vấn đề này thông

qua khái niệm Generic.

7


9/18/2018

Generic Types
 Generic là 1 tính năng mới trong .NET


Framework 2.0 và và được tích hợp sâu trong
Common Language Runtime (CLR).
 Trong .NET Framework, Generic được giới thiệu
là khái niệm về các kiểu tham số và được dùng
để thiết kế class và method nhằm để trì hỗn chỉ
ra kiểu dữ liệu cho đến khi chúng được khai báo
hoặc khởi tạo.
 Một trong những điểm nổi bật của kiểu Generic
là cho phép kiểm tra cú pháp trong lúc biên dịch.
Có thể sử dụng nhiều kiểu dữ liệu khác nhau với
cùng 1 đoạn code (tương tự như khái niệm
Template trong C++)

Tham số T
 Bằng cách sử dụng tham số T là tham số chung, cho phép

tạo 1 class duy nhất và sử dụng cho nhiều type khác
nhau.
public class GenericStack<T>
{
T[] _data = new T[100];
int _curIdx = -1;
public void Push(T value)
{
_data[++_curIdx] = value;
}
public T Pop()
{
return _data[_curIdx--];

}
}
//... sử dụng
GenericStack<string> s = new GenericStack<string>();

8


9/18/2018

Generic Methods
 Là các hàm thông dụng (cách hành xử chung cho

các type khác nhau) nên cài đặt theo kiểu
Generic (sử dụng các tham số đầu vào hay đầu
ra là generic)
static void Swap<T>(ref T x, ref T y)
{
T temp;
temp = x;
x = y;
y = temp;
}

int iX = 2, iY = 6;
float fX = 2.3f, fY = 6.7f;
Swap<int>(ref iX, ref iY);
Swap<float>(ref fX, ref fY);

C# keyword: default

 Lấy giá trị mặc định với các tính chất sau:
 Numeric values thì giá trị default là 0
 Reference types thì giá trị default là null
 Các Field được gán default là 0 (nếu là value

type) hoặc null (nếu là reference type)
class GenericTest<T>
{
T x, y;
public GenericTest()
{
x = default(T);
y = default(T);
}
}

9


9/18/2018

Constraining Type Parameters
Ý nghĩa

Generic Constraint

where T : struct

T chỉ được áp dụng cho Value type


where T : class

T phải là reference type

where T : new()

T phải là type có 1 default constructor

where T : NameOfBaseClass

T phải được dẫn xuất từ class
NameOfBaseClass

where T : NameOfInterface

T phải implement interface
NameOfInterface

class GenericTest<T> where T : struct
{
T x, y;
}
GenericTest<int> gti = new GenericTest<int>();
error???
GenericTest<string> gts = new GenericTest<string>();

List<T>
 Thuộc namespace System.Collections.Generic
// khởi tạo
var lP = new List<CTest> {

new CTest { X = 1, Y = 2 },
new CTest(),
new CTest { X = 7, Y = 3 }
};
// thêm 1 phần tử
lP.Add(new CTest { X = 4, Y = 2 });
// thêm nhiều phần tử
lP.AddRange(new CTest[] { new CTest(), new CTest() });
// duyệt
for (int i = 0; i < lP.Count; i++)
{
Console.WriteLine("<{0}, {1}>", lP[i].X, lP[i].Y);
}

10


9/18/2018

Nội dung
 Một vài C# keyword
 Collections
 Generics
 Delegates

Delegates
 Delegate là kiểu dữ liệu tham chiếu được dùng

để đóng gói một phương thức với tham số và
kiểu trả về xác định.

 Với delegate một chương trình có thể thực thi
động (dynamic) các phương thức (method) khác
nhau trong quá trình chạy (runtime).
 Sau khi method được đóng gói trong delegate,
nó sẽ được thực thi (called) khi delegate được
chạy (invoked).
 Khai báo delegate
[modifiers] delegate <return type> <delegate name>([parameter list]);

11


9/18/2018

Ví dụ
// khai báo delegate
delegate decimal ProcessCalculateHandler(decimal d1, decimal d2);
static void Main(string[] args)
{
// tạo đối tượng delegate
ProcessCalculateHandler pcA = new ProcessCalculateHandler(AddCalculate);
TinhToan(pcA);
}
// method hợp với delegate đã khai báo

static decimal AddCalculate(decimal d1, decimal d2)
{
return d1 + d2;
}
// phương thức có tham số là delegate

static void TinhToan(ProcessCalculateHandler pc)
{
if (pc != null)
{
Console.WriteLine("Ket qua: {0}", pc(123, 456));
}
}

Ứng dụng đơn giản
 Xét class SinhVien
public class SinhVien
{
public string MSSV { get; set; }
public string HoTen { get; set; }
public string QueQuan { get; set; }
}

 Với mảng các đối tượng SinhVien
SinhVien[] arrSV;

 Cần sắp xếp mảng theo các tiêu chí khác nhau, giải

pháp???

12


9/18/2018

Giải pháp 1

 Sử dụng các hàm khác nhau
static void SapXepTheoMSSV(SinhVien[] arrSV)
{
for (int i = 0; i < arrSV.Length - 1; i++)
{
for (int j = i + 1; j < arrSV.Length; j++)
{
if (arrSV[i].MSSV.CompareTo(arrSV[j].MSSV) > 0)
{
SinhVien sv = arrSV[i];
arrSV[i] = arrSV[j];
arrSV[j] = sv;
}
}
}
}
static void SapXepTheoHoTen(SinhVien[] arrSV)
{
//...
}
static void SapXepTheoQueQuan(SinhVien[] arrSV)
{
//...
}

Giải pháp 2
 Sử dụng delegate
delegate int SoSanhHandler(SinhVien sv1, SinhVien sv2);
static void SapXep(SinhVien[] arrSV, SoSanhHandler ssFunc)
{

for (int i = 0; i < arrSV.Length - 1; i++)
{
for (int j = i + 1; j < arrSV.Length; j++)
{
if (ssFunc(arrSV[i], arrSV[j]) > 0)
{
SinhVien sv = arrSV[i];
arrSV[i] = arrSV[j];
arrSV[j] = sv;
}
}
}
}

13


9/18/2018

Sử dụng delegate để gửi thông báo
 Xét yêu cầu quản lý cấp độ thẻ thành viên của

siêu thị. Khi khách hàng tích lũy điểm nhờ mua
hàng đến những mức độ nhất định sẽ được nâng
cấp độ thẻ và siêu thị cần chúc mừng khách
hàng.
 Tìm giải pháp phù hợp???

class KhachHang
class KhachHang

{
static uint muc1 = 20, muc2 = 30, muc3 = 50;
public string HoTen { get; }
public string CapDo { get; private set; }
public uint DiemTichLuy { get; private set; }
public KhachHang(string ht)
{
HoTen = ht;
DiemTichLuy = 0;
CapDo = "Cap0";
}
public void TichDiem(uint dtl)
{
DiemTichLuy += dtl;
if (DiemTichLuy >= muc3)
{
CapDo = "Cap3";
}
//...
}
}

14


9/18/2018

class SieuThi
class SieuThi
{

List<KhachHang> DsKhachHang = new List<KhachHang>();
public void ThemKhachHang(KhachHang kh)
{
DsKhachHang.Add(kh);
}
public void ThucHienTichDiem()
{
var rd = new Random();
foreach (KhachHang kh in DsKhachHang)
{
kh.TichDiem((uint)rd.Next(1, 10));
}
}
public void ChucMungKH(KhachHang kh)
{
Console.WriteLine("{0} dat {1}", kh.HoTen, kh.CapDo);
}
}

Hàm main
static void Main(string[] args)
{
var st = new SieuThi();
st.ThemKhachHang(new KhachHang("ABC"));
do
{
st.ThucHienTichDiem();
//...
} while (Console.ReadKey().Key != ConsoleKey.Q);
}


15


9/18/2018

Giải pháp 1
 Thêm cờ kiểm soát việc chúc mừng của siêu thị

trong class KhachHang
public bool ChuaChucMung { get; set; }

 Thêm phương thức tổng duyệt khách hàng trong

class SieuThi
public void TongDuyetKH()
{
string cdHienTai = null;
foreach (KhachHang kh in DsKhachHang)
{
if (kh.ChuaChucMung)
{
ChucMungKH(kh);
kh.ChuaChucMung = false;
}
}
}

 Hàm tích điểm
public void TichDiem(uint dtl)

{
string cdOld = CapDo;
DiemTichLuy += dtl;
if (DiemTichLuy >= muc3)
{
CapDo = "Cap3";
}
else if (DiemTichLuy >= muc2)
{
CapDo = "Cap2";
}
else if (DiemTichLuy >= muc1)
{
CapDo = "Cap1";
}
if (cdOld != CapDo)
{
ChuaChucMung = true;
}
}

16


9/18/2018

 Hàm main
static void Main(string[] args)
{
var st = new SieuThi();

st.DsKhachHang.Add(new KhachHang("ABC"));
do
{
Console.WriteLine("Tich diem...");
st.ThucHienTichDiem();
st.TongDuyetKH();
} while (Console.ReadKey().Key != ConsoleKey.Q);
}

Giải pháp 2
 Tạo delegate cho KhachHang
class KhachHang
{
public delegate void ThayDoiCapDoHandler(KhachHang kh);
ThayDoiCapDoHandler handlers;
...
public void TichDiem(uint dtl)
{
...
if (cdOld != CapDo)
{
if (handlers != null)
{
handlers(this);
}
}
}
public void DangKyTheoDoi(ThayDoiCapDoHandler h)
{
handlers = h;

}
}

17


9/18/2018

 Thay đổi trong class SieuThi
public void ThemKhachHang(KhachHang kh)
{
DsKhachHang.Add(kh);
kh.DangKyTheoDoi(new
KhachHang.ThayDoiCapDoHandler(ChucMungKH));
}

 Mục tiêu là đăng ký theo dõi KhachHang ngay khi

tạo.
 Hàm main sẽ không cần thay đổi…

Đánh giá 2 giải pháp?
 Về vấn đề nơi kiểm sốt để phát sinh thơng báo?
 Khi có số lượng lớn đối tượng có thể phát sinh

thông báo?

18



9/18/2018

Multicasting
 Cơ chế multicasting cho phép gọi hai hay nhiều

phương thức thực thi thơng qua một ủy quyền
đơn. Mục đích chính là với một delegate có thể
gọi thực hiện nhiều hơn một phương thức. Để
thực hiện được thì kiểu trả về của delegate phải
là kiểu void.
 Ví dụ:
myMulticastDelegate = Writer + Logger;
myMulticastDelegate += Transmitter;

Ví dụ
delegate void MultiHandler(decimal d1, decimal d2);
static void Main(string[] args)
{
MultiHandler md = new MultiHandler(Func1);
md += new MultiHandler(Func2);

md(123, 456);
}
static void Func1(decimal d1, decimal d2)
{
Console.WriteLine("{0} + {1}= {2}", d1, d2, d1 + d2);
}
static void Func2(decimal d1, decimal d2)
{
Console.WriteLine("{0} - {1}= {2}", d1, d2, d1 - d2);

}

19


9/18/2018

Áp dụng
 Xét lại ví dụ về Siêu thị và Khách hàng nếu có

thêm các bộ phận hay đối tác cũng cần quan tâm
đến việc thay đổi cấp độ của khách hàng?
 Bộ phận khuyến mãi cần gửi ưu đãi khuyến mãi

mới
 Đối tác Tài chính muốn tặng ưu đãi

 Thay đổi hàm đăng ký để áp dụng multicasting
public void DangKyTheoDoi(ThayDoiCapDoHandler h)
{
handlers += h;
}

 Xây dựng class CtyTaiChinh
class CtyTaiChinh
{
static string TenCty = "CtyABC";
public static void UuDaiMoi(KhachHang kh)
{
Console.WriteLine("{0} uu dai moi cho {1}",

TenCty, kh.HoTen);
}
}

20



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×