RSS

Category Archives: C# Nâng cao

Lập trình hướng đối tượng với mô hình 3 lớp (3 layers)

Lưu ý: Các bạn không nên nhầm lẫn khái niệm lớp(layer) trong phần này với khái niệm lớp(class) của các ngôn ngữ lập trình hướng đối tượng.

Trong phát triển ứng dụng, để dễ quản lý các thành phần của hệ thống, cũng như không bị ảnh hưởng bởi các thay đổi, người ta hay nhóm các thành phần có cùng chức năng lại với nhau và phân chia trách nhiệm cho từng nhóm để công việc không bị chồng chéo và ảnh hưởng lẫn nhau. Ví dụ trong một công ty bạn có từng phòng ban, mỗi phòng ban sẽ chịu trách nhiệm một công việc cụ thể nào đó, phòng này không được can thiệp vào công việc nội bộ của phòng kia như Phòng tài chính thì chỉ phát lương, còn chuyện lấy tiền đâu phát cho các anh phòng Marketing thì các anh không cần biết.

Trong phát triển phần mềm, người ta cũng áp dụng cách phân chia chức năng này. Bạn sẽ nghe nói đến thuật ngữ kiến trúc đa tầng/nhiều lớp, mỗi lớp sẽ thực hiện một chức năng nào đó, trong đó mô hình 3 lớp là phổ biến nhất. 3 lớp này là gì? Là Presentation, Business Logic, và Data Access. Các lớp này sẽ giao tiếp với nhau thông qua các dịch vụ(services) mà mỗi lớp cung cấp để tạo nên ứng dụng, lớp này cũng không cần biết bên trong lớp kia làm gì mà chỉ cần biết lớp kia cung cấp dịch vụ gì cho mình và sử dụng nó mà thôi.

1. Giới thiệu các thành phần của mô hình 3layer

Mô hình layer gồm có 3 layer:

  • Layer GUI (Graphics User Interface)
  • Layer Business Logic (Đây là layer để xử lý các dữ liệu, thông tin trước khi đưa lên giao diện hoặc đưa xuống dữ liệu.)
  • Layer Data Access – Layer này sẽ nói chuyện Data.

 

1.1. GUI Layer.

  • Đây là layer tạo lên giao diện cho người dùng, nó sẽ là nơi tiếp nhận và kết xuất ra kết quả của chương trình cho bạn.
  • Nó có nhiệm vụ xử lý, kiểm tra các dữ liệu nhập vào ( ví như ở TextBox này nó phải là số, số phải từ 1-9….).
  • Nó tiếp nhận các Event của người dùng, kiểm tra dữ liệu được nhập vào, gửi yêu cầu xử lý xuống tầng kế tiếp.

1.2. Business Logic Layer

  • Đây là layer xử lý chính các dữ liệu trước khi được đưa lên hiển thị trên màn hình hoặc xử lý các dữ liệu trước khi lưu dữ liệu xuống cơ sở dữ liệu.
  • Đây là nơi đê kiểm tra các yêu cầu nghiệp vụ, tính toán các yêu cầu nghiệp vụ.
  • Tại đây các tính năng tính toán trong chương trình sẽ được thực thi. (Như tính lương theo một công thức.)

1.3. Data Access Layer

  • Layer này sẽ lo nhiệm vụ là đọc cơ sở dữ liệu lên, cập nhật cơ sở dữ liệu, update cơ sở dữ liệu.
  • Nói chung là nó làm nhiệm vụ là nói chuyện phải trái với database.

1.4. Cách các layer “nói chuyện” với nhau.

Vấn đề đặt ra ở đây là 3 layer này ‘Nói chuyện’ với nhau như thế nào

Nhìn vào sơ đồ ta cũng sẽ nhận được câu trả lời:

Quá trình hiển thị dữ liệu:

Data Access layer nói chuyện với Database và lấy dữ liệu lên theo một cách nào đó (có thể là bằng câu lệnh select hay thông qua proceduce) lúc này sau khi lấy được dữ liệu lên thì nó sẽ đẩy lên Business layer tại đây Business cần nhào bột, thêm mắm muối rồi đẩy nó lên trên GUI và tại GUI nó sẽ hiển thị lên cho người dùng

Quá trình đưa dữ liệu xuống.

Người dùng thao tác với GUI layer sau đó ra lệnh thực hiện (ví như Insert) sau đó hệ thống sẽ kiểm tra các thông tin người dùng nhập vào nếu thỏa đi xuống tiếp layer Business để tiếp tục được nhào nặn, tính toán và kiểm tra sau khi xong thì dữ liệu được đẩy xuống thông tin phía dưới Data Access Layer sau đó tại DataAccess Layer sẽ thực thi nó xuống database.

1.5. Cách xử lý “lỗi” trong mô hình 3 layer.

Một khi gặp lỗi (các trường hợp không đúng dữ liệu) thì đang ở layer nào thì quăng lên trên layer cao hơn nó 1 bậc cho tới GUI thì sẽ quăng ra cho người dùng biết.

1.6. Demo mô hình 3 layer trong chương trình quản lý

DOWNLOAD DEMO

Nguồn: vi-infotech.com

 

[WCF] Giới thiệu

1. Khái niệm WCF

– WCF là công nghệ nền tảng nhằm thống nhất nhiều mô hình lập trình giao tiếp được hỗ trợ trong .NET 2.0 thành một mô hình duy nhất. Vào tháng 11 năm 2005, .NET 2.0 được Microsoft phát hành trong đó có cung cấp các hàm API riêng biệt cho các liên lạc dựa trên SOAP để tối đa hoá sự làm việc giữa các nền tảng sử dụng Web Services, đồng thời .NET 2.0 còn cung cấp các API để tối ưu việc liên lạc dựa trên mã nhị phân giữa các ứng dụng chạy trên hệ thống Windows gọi là .NET Remoting, các API cho các giao dịch phân tán, và API cho liên lạc dị bộ. WCF thống nhất các API này thành một mô hình duy nhất nhằm đáp ứng mô hình lập trình hướng dịch vụ.

– WCF có thể sử dụng các bản tin SOAP giữa hai tiến trình, do đó làm cho các ứng dụng dựa trên WCF có thể làm việc với các tiến trình khác thông qua việc giao tiếp sử dụng bản tin SOAP. Khi một tiến trình WCF liên lạc với một tiến trình không là WCF, các bản tin SOAP được mã hoá trên cơ sở XML, nhưng khi nó liên lạc với một tiến trình WCF khác, bản tin SOAP có thể được tối ưu hoá dựa trên mã hoá nhị phân.

2. Tại sao phải sử dụng WCF

– Như phần trên đã trình bày, .NET 2.0 hỗ trợ rất nhiều phương pháp liên lạc giữa các ứng dụng khác nhau nhằm vào các mục tiêu khác nhau. Các phương pháp liên lạc này khá phức tạp và phải mất nhiều thời gian để làm chủ được công nghệ. Tuy nhiên kiến thức thu được từ việc triển khai một phương pháp ít có khả năng dùng được khi làm việc với phương pháp khác.

– Với việc ra đời của WCF, mọi phương pháp liên lạc trước kia đều có thể thực hiện trên WCF. Do vậy nhà phát triển chỉ cần làm chủ được công nghệ WCF là có thể xây dựng các ứng dụng một cách nhanh chóng.

– WCF là một mô hình lập trình cho phép nhà phát triển xây dựng các giải pháp dịch vụ đảm bảo tính ổn định, và bảo mật và thậm chí là đảm bảo giao dịch. Nó làm đơn giản hoá việc phát triển các ứng dụng nối kết và đưa ra cho nhà phát triển những giá trị mà có thể họ chưa nhận ra ngay, đó là cách tiếp cận phát triển hệ thống phân tán thống nhất, đơn giản, và quản lý được.

– Do WCF được xây dựng trên cơ sở của .NET Framework 2.0 CLR, nó là tập các lớp cho phép các nhà phát triển xây dựng các ứng dụng hướng dịch vụ bằng môi trường lập trình quen thuộc của họ như VB.NET hay C#.

3. Kiến trúc WCF

3.1. Contracts

– Các contract trong WCF cũng giống như các hợp đồng/hiệp định mà bạn ký trong đời sống thật. Một hợp đồng bạn ký có thể chứa các thông tin như kiểu công việc bạn sẽ làm, và những thông tin mà bạn muốn đưa ra cho các bên khác. WCF contract cũng chứa các thông tin tương tự như vậy. Contract định nghĩa các đặc tả trong hệ thống bản tin.Thông thường có các loại contract sau:

  • Contract dữ liệu mô tả các tham số cho các bản tin mà một dịch vụ có thể tạo ra hay sử dụng. Các tham số bản tin được định nghĩa bằng các tài liệu sử dụng ngôn ngữ đặc tả XML Schema (XSD), điều này cho phép các hệ thống hiểu XML có thể xử lý tài liệu dễ dàng. Các dịch vụ khi liên lạc với nhau có thể không cần đồng ý với nhau về các kiểu, nhưng cần đồng ý về contract dữ liệu, nghĩa là đồng ý về các tham số và các kiểu trả về.
  • Contract bản tin định nghĩa các phần có trong bản tin sử dụng các giao thức SOAP, và nó cho phép điều khiển sâu hơn tới các phần trong bản tin khi có yêu cầu sự chính xác như vậy.
  • Contract dịch vụ đặc tả chi tiết các phương thức của dịch vụ, và được phân phối như là một giao diện trong các ngôn ngữ lập trình như Visual Basic hay Visual C#. Có thể hình dung về contract dịch vụ một cách gián tiếp như sau: „Đây là các kiểu dữ liệu của các bản tin của tôi, đây là nơi tôi cung cấp, và đây là các giao thức mà tôi có thể liên lạc”
  • Các chính sách và các kết nối (bindings) mô tả các điều kiện cần có để giao tiếp với một dịch vụ. Các chính sách sẽ bao gồm cả các yêu cầu về bảo mật và các điều kiện khác cần phải có khi kết nối với một dịch vụ.

3.2. Service Runtime

– Lớp dịch vụ thực thi chứa các hành xử sẽ xảy ra trong quá trình thực hiện của dịch vụ, nghĩa là các hành xử thực thi của dịch vụ. Ta sẽ thấy một số các hành xử như sau:

  • Throttling behavior: Điều khiển luồng nhằm quy định xem có bao nhiêu bản tin được xử lý
  • Error behavior: Hành xử lỗi quy định những hành động khi lỗi xảy ra trong hệ thống
  • Metadata behavior: Hành xử với các siêu dữ liệu quy định xem làm thế nào và khi nào thì các siêu dữ liệu được đưa ra bên ngoài dịch vụ
  • Instance behavior: Hành xử thực thể quy định xem có bao nhiêu thực thể của dịch vụ đó được chạy
  • Transaction behavior: Hành xử giao dịch cho phép việc rollback các giao dịch nếu xảy ra lỗi
  • Message inspection: Kiểm tra bản tin đem lại cho dịch vụ khả năng kiểm tra tất cả hay một số phần của bản tin
  • Dispatch behavior: Khi một bản tin được xử lý bởi nền tảng WCF, dịch vụ Dispatch behavior xác định xem bản tin được xử lý như thế nào.
  • Concurrency behavior: Hành xử đồng thời xác định xem việc xử lý thế nào với việc đa luồng của mỗi dịch vụ hay mỗi thực thể của dịch vụ. Hành xử này giúp cho việc điều khiển số lượng luồng có thể truy nhập tới một thực thể của dịch vụ.
  • Parameter filtering: Khi một bản tin được đưa tới một dịch vụ, sẽ xảy ra một số hành động dựa trên nội dung phần đầu đề của bản tin. Phần lọc tham số sẽ thực hiện lọc các đầu đề bản tin và thực hiện các hành động đặt sẵn dựa trên việc lọc đầu đề bản tin.

3.3. Messaging

– Lớp bản tin là tập hợp các kênh. Mỗi kênh là một thành phần xử lý bản tin theo một cách nào đó. Một tập các kênh thường được gọi là ngăn xếp kênh. Các kênh làm việc trên bản tin và trên đầu đề của bản tin. Lớp này khác với lớp thực thi dịch vụ chủ yếu bởi sự khác nhau trong việc xử lý nội dung bản tin. Có hai kênh khác nhau là kênh vận chuyển (transport channel) và kênh điều khiển (control channel).

  • Kênh vận chuyển phụ trách việc đọc và ghi các bản tin từ mạng (network) hoặc từ một số điểm giao dịch bên ngoài)
  • Kênh điều khiển thực hiện xử lý bản tin theo giao thức, thông thường làm việc bằng cách đọc và ghi thêm các đầu đề cho bản tin

3.4. Activation and hosting

– Nhìn một cách tổng thể thì một dịch vụ thực chất là một chương trình. Cũng giống như các chương trình khác, một dịch vụ cần phải chạy trong một tệp thực thi. Dịch vụ này thường được gọi là dịch vụ tự chứa.

– Các dịch vụ còn có thể được chứa, hoặc chạy trong một tệp thực thi được quản lý bởi một agent bên ngoài như IIS hay Windows Activation Services (WAS). WAS cho phép WCF được kích hoạt một cách tự động khi phân phối tới một máy tính có chạy WAS.

4. Các tính năng của WCF

4.1. Transaction (Giao dịch)

– Một giao dịch là một đơn vị của công việc. Một giao dịch đảm bảo chắc chắn rằng mọi thứ diễn ra trong giao dịch thành công hay thất bại đều là kết quả tổng thể. Ví dụ, nếu một giao dịch chứa ba mục công việc cần thực hiện, trong quá trình thực hiện giao dịch, một trong số các mục đó bị thất bại, khi đó cả ba mục sẽ là thất bại. Giao dịch chỉ thành công khi cả ba mục công việc đều thành công. Giao dịch thường thấy trong các thao tác với cơ sở dữ liệu.

– WCF cho phép đưa vào việc xử lý giao dịch như trên với các liên lạc. Nhà phát triển có thể nhóm các liên lạc với nhau thành các giao dịch. Ở mức doanh nghiệp, tính năng này cho phép bạn thực hiện các công việc giao dịch qua các nền tảng khác nhau.

4.2. Host (Chứa)

– WCF cho phép các dịch vụ được chứa trong một số lớn các môi trường khác nhau, như Windows NT Services, Windows Forms, và ứng dụng console, cũng như ở trên IIS (Internet Information Server) và WAS (Windows Activation Services).

– Chứa ứng dụng trên IIS còn có thêm các lợi điểm khác là dịch vụ có thể nhận các ưu điểm của rất nhiều tính năng có sẵn trên IIS, ví dụ IIS có thể điều khiển một cách tự động việc bắt đầu hay kết thúc một dịch vụ.

4.3. Bảo mật

– Bảo mật là tính năng không thể thiếu trong WCF nói riêng và trong liên lạc nói chung. Trong WCF, tất cả mọi thứ từ các bản tin tới các client hay server đều phải xác thực và WCF có tính năng để đảm bảo rằng các bản tin không bị lẫn trong quá trình vận chuyển. WCF bao gồm việc đảm bảo tính toàn vẹn và bảo mật của bản tin.

– WCF còn cho phép bạn tích hợp ứng dụng của bạn với cơ sở hạ tầng bảo mật sẵn có, bao gồm cả các chuẩn bên ngoài môi trường Windows bằng cách sử dụng các bản tin SOAP bảo mật.

 

Nguồn: vi-infotech.com

 

Sử dụng WrapPanel trong Windows Phone 7

I. Introduction

  • Trong Windows Phone có sẵn một số Container như Grid, StackPanel, Canvas, tuy nhiên WrapPanel thì  vẫn chưa có, mãi cho đến bộ Silverlight for Windows Phone toolkit ra đời thì WrapPanel mới được bổ sung
  • Trong bài này mình xin chia sẻ về cách dùng WrapPanel trong WP7

II. Fundamental

  • WrapPanel thường được dùng để đổ dữ liệu theo luồng, vd như nhiều hình vuông sắp xếp từ trái sang phải ….
  • Để sử dụng WrapPanel chúng ta phải cài đặt bộ Silverlight for Windows Phone Toolkit

Read the rest of this entry »

 
 

Hướng dẫn Debug chương trình trong Visual Studio–Visual Studio Debugging Tutorial.

Khi học lập trình có rất nhiều sinh viên rất ít sử dụng đến công cụ Debug của Visual Studio. Khi chương trình gặp lỗi hay cho ra kết quả sai, bạn không biết tại sao và cắm đầu vào đọc lại từng dòng code. Trong khi công cụ Debug của Visual Studio (VS 2010) là một công cụ mạnh để thực hiện việc trên. Do đó chúng ta sẽ tìm hiểu cách sử dụng công cụ này.

Bạn muốn xem một biến cục bộ trong chương trình C# khi nó thực thi thay đổi giá trị như thế nào, điều này rất hữu ích khi bạn muốn đảm bảo các giá trị kết quả của bạn được chính xác. Ở đây chúng ta sẽ tìm hiểu thông qua ví dụ về cách Debug các biến của bạn trong môi trường Visual Studio 2010.

image

1. Debug C# với Visual Studio 2010

Đầu tiên chúng ta nhìn vào một chương trình ngắn viết bằng ngôn ngữ C# có nhiều biến cục bộ trong đó. Để xem bên trong một hàm bạn cần sử dụng một Break Point(Điểm dừng) ở một nơi trong khối lệnh C# mà bạn có. Ví dụ tôi sẽ sử dụng Chương trình đơn giản  là:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Debugging
{
    class Program
    {
        static void Main(string[] args)
        {
            int a;
            int b;
            a = b = 10;
            int c = 90;
            String s = "Hello Thanh Cuong!";
            Console.WriteLine(" a + b + c = {0}", a + b + c);
            Console.WriteLine(s);
        }
    }
}

2. Add Debugging BreakPoint

Ở đây tôi sẽ thêm một Breackpoint vào đầu chương trình ở trên. Trên bên trái của tab mã nguồn bạn nhấp chuột vào dòng muốn debug hoặc đưa con nháy tới dòng muốn debug và nhấn F9 sẽ thấy một dấu hình tròn màu xám trước dòng đó. Như hình bên dưới. Nhấn F5 để chạy chương trình, khi chương trình chạy đến dòng lệnh  mà bạn đặt breakpoint nó sẽ dừng lại và chương trình debug sẽ được mở ra.

image

3. Khi Debugger được mở:

Khi bạn thiết lập Breakpoint (vòng tròn nhỏ màu xám) trên mã lệnh của bạn, công cụ debug sẽ mở ra khi chương trình chạy tới điểm mà bạn đặt BreakPoint. Chương trình sẽ tạm dừng ở đó. Để bạn có thể sử dụng để kiểm tra các biến mà mình nghi ngờ là chương trình có thể chạy sai ở đó.

4. Bắt đầu Debug

Để bắt đầu Debug bạn nhấp chuột vào nút có mũi tên màu xanh ở thanh công cụ trong Visual Studio của bạn hoặc nhấn F5 như hình bên dưới

image

5. Chờ chương trình chạy đến BreakPoint

Khi chương trình thực thi đến Breackpoint mà bạn đã đánh dấu thì dòng đó sẽ chuyển sang màu vàng như hình bên dưới.

image

Bây giờ bạn có thể kiểm tra các biến cục bộ của chương trình bằng cách vào menu Debug –> Windows –> Locals (hoặc ấn Alt F4 )

image

6. Sử dụng tính năng locals để xem giá trị của các biến cục bộ

image

Bây giờ bạn có thể thấy các biến cục bộ trong chương trình của mình và giá trị của nó khi chương trình chạy đến đó. Bạn có thể sử dụng chức năng này để biết được mỗi giá trị thay đổi như thế nào khi chương trình chạy đến đó.

7. Step over statements

Trong phần này, chúng ta sẽ tìm hiểu cách lựa chọn trong visual studio debugger. Thông thường trong chương trình Debug bạn muốn tiến một bước , bạn nhấn vào nút màu xanh ở thanh công cụ để đến điểm breakpoint tiếp theo.

– Step into (F11): Step into thực thi chỉ gọi chính nó, sau đó dừng ở dòng đầu tiên của mã lệnh trong hàm.

– Step over (F10): Di chuyển đến bước kế tiếp trong mã của bạn, nhưng không dừng bên trong mỗi phương thức.

– Step out: bỏ qua phần còn lại của các phương thức hiện hành và đi vào các phương thức được gọi.

image

Các bước thực hiện trong ví dụ này, tôi sử dụng step over (F10), điều này cho phép chúng ta xem giá trị của tất của tất cả các biến.

8. Thông tin thêm

Công cụ Debug của visual 2010 là khá toàn diện và hiệu quả cho hầu hết các vấn đề. Nó bao gồm nhiều sự lựa chọn hơn, bao gồm: Call Stack, Command Windows, Exception, Autos. Bạn có thể cấu hình các breakpoint chỉ đơn giản là viết một thông điệp trong console… Điều này rất tốt để thử nghiệm hiệu suất.

9.  Nếu các công cụ khác không có trình Debug bạn nên làm gì?

Khi sử dụng các trình biên dịch không có công cụ Debug hoặc công cụ debug yếu. Bạn có thể sử dụng các lệnh để in kết quả của các biến ra màn hình để kiểm tra việc hoạt động của các biến đó. Tuy cách này hơi lâu hơn công cụ Debug của Visual Studio nhưng nó cũng khá hiệu quả trong việc kiểm tra và theo dõi các biến.

Bài viết tiếp theo sẽ trình bày các mẹo khác khi debug chương trình.

Bài viết được tham khảo tại dotnetperls.com/debugging

Nguồn: http://thanhcuong.wordpress.com

 

Nhãn: , , ,

Giới thiệu về Delegate, và cách sử dụng Delegate trong C#

Delegate có thể được xem như là kiểu đối tượng mới trong C#, mà có môt số điểm quen thuộc với lớp. Chúng tồn tại trong tình huống mà ta muốn truyền phương thức xung quanh những phương thức khác, để minh hoạ ta xem dòng mã sau:

         int i = int.Parse(“99″);

-   Chúng ta quen với việc truyền dữ liệu đến một phương thức như là thông số, vì vậy ý tường truyền phương thức như là thông số nghe có vẻ hơi lạ đối với chúng ta. Tuy nhiên có trường hợp mà ta có 1 phương thức mà làm 1 điều gì đó, nhiều hơn là xử lí dữ liệu, phương thức đó có thể cần làm điều gì đó mà liên quan đến việc thực thi phương thức khác phức tạp hơn, bạn không biết vào lúc nào thì phương thức thứ hai sẽ được biên dịch. Thông tin đó chỉ biết vào lúc chạy, và chính vì lí do đó mà phương thức 2 sẽ cần truyền vào như là thông số cho phương thức đầu tiên.  Điều này nghe có vẻ hơi khó hiểu, nhưng nó sẽ được làm rõ hơn trong 1 vài ví dụ sau:

  • Luồng bắt đầu: C# có thể bảo máy tính bắt đầu một chuỗi thực thi mới song song với việc thực thi đương thời. 1 chuỗi liên tiếp này gọi là luồng,và việc bắt đầu này được làm bằng cách dùng phương thức, Start() trên 1 thể hiện của lớp cơ sở System.Threading.Thread. Khi chương trình bắt đầu chạy, nơi nó bắt đầu là main(). Tương tự như vậy khi bạn muốn máy tính chạy một chuỗi thực thi thì bạn phải báo cho máy tính biết bắt đầu chạy là ở đâu. Bạn phải cung cấp cho nó chi tiết của phương thức mà việc thực thi có thể bắt đầu – nói cách khác, phương thức Thread.Start() phải lấy 1 thông số mà định nghĩa phương thức được thi hành bởi luồng.
  • Lớp thư viện chung . khi 1 nhiệm vụ chứa đựng nhiệm vụ con mà mã của các nhiệm vụ con này được viết trong các thư viện chỉ có sử dụng thư viện mới biết nó làm gì. Ví dụ, chúng ta muốn viết một lớp chứa một mảng đối tuợng và sắp nó tăng dần. 1 phần công việc được lặp lại là lấy 2 đối tượng trong lớp so sánh với nhau để xem đối tượng nào đứng truớc.nếu ta muốn lớp có khả năng sắp xếp bất kì đối tượng nào, không có cách nào có thể làm được việc so sánh trên. Mã client dùng mảng đối tượng của ta sẽ bảo cho ta biết cách so sánh cụ thể đối tượng mà nó muốn sắp xếp. Nói cách khác, mã client sẽ phải truyền cho lớp của ta phương thức thích hợp mà có thể được gọi, để làm việc so sánh.
    Nguyên tắc chung là: mã của ta sẽ cần thông báo cho thời gian chạy .NET biết phương thức nào xử lí tình huống nào.

-   Vì thế chúng ta phải thiết lập những nguyên tắc mà đôi lúc, những phương thức cần lấy chi tiết của phương thức khác như là thông số. Kế tiếp chúng ta sẽ minh họa cách làm điều đó, cách đơn giản nhất là truyền tên của phương thức như là thông số. Giả sử chúng ta muốn bắt đầu một luồng mới, và chúng ta có phương thức được gọi là entrypoint(), mà ta muốn luồng bắt đầu chạy từ đó:

void EntryPoint()
{
    // làm những gì luồng mới cần làm
}

– Có thể chúng ta bắt đầu luồng mới với một đoạn mã:

    Thread NewThread = new Thread();
    Thread.Start(EntryPoint); // sai

-  Thật sự đây là cách đơn giản nhất. Trong một vài ngôn ngữ dùng cách này như C và C++ (trong c và c++ thông số entrypoint là con trỏ hàm). Không may, cách thực thi trực tiếp này gây ra một số vấn đề về an toàn kiểu. Nhớ rằng ta đang lập trình hướng đối tượng, phương thức hiếm khi nào tồn tại độc lập, mà thường là phải kết hợp với phương thức khác trưóc khi được gọi. Vì vậy .NET không cho làm điều này, thay vào đó nếu ta muốn truyền phương thức ta phải gói chi tiết của phương thức trong một loại đối tượng mới là 1 delegate. delegate đơn giản là một kiểu đối tượng đặc biệt – đặc biệt ở chỗ, trong khi tất cả đối tượng chúng ta định nghĩa trước đây chứa đựng dữ liệu, thì delegate chứa đựng chi tiết của phương thức.

1.  Dùng delegate trong C#

– Đầu tiên ta phải định nghĩa delegate mà ta muốn dùng ,nghĩa là bảo cho trình biên dịch biết loại phương thức mà delegate sẽ trình bày.sau đó ta tạo ra các thể hiện của delegate.

Cú pháp:

delegate void VoidOperation(uint x); 

-  Ta chỉ định mỗi thể hiện của delegate có thể giữ một tham chiếu đến 1 phương thức mà chứa một thông số uint và trả vầ kiểu void.

-  Ví dụ khác: nếu bạn muốn định nghĩa 1 delegate gọi là twolongsOp mà trình bày 1 hàm có 2 thông số kiểu long và trả về kiểu double. ta có thể viết :

delegate double TwoLongsOp(long first, long second);

-  Hay 1 delegate trình bày phương thức không nhận thông số và trả về kiểu string.

delegate string GetAString();

-  Cú pháp cũng giống như phương thức, ngoại trừ việc không có phần thân của phương thức, và bắt đầu với delegate, ta cũng có thể áp dụng các cách thức truy nhập thông thường trên một định nghĩa delegate – public, private, protected …

public delegate string GetAString();

-  Mỗi lần ta định nghĩa một delegate chúng ta có thể tạo ra một thể hiện của nó mà ta có thể dùng đề lưu trữ các chi tiết của 1 phưong thức cụ thể.

-  Lưu ý: với lớp ta có 2 thuật ngữ riêng biệt: lớp để chỉ định nghĩa chung, đối tượng để chỉ một thể hiện của 1 lớp, tuy nhiên đối với delegate ta chỉ có một thuật ngữ là ’1 delegate’ khi tạo ra một thể hiện của delegate ta cũng gọi nó là delegate. Vì vậy cần xem xét ngữ cảnh để phân biệt.

-  Đoạn mã sau minh hoạ cho 1 delegate:

static void Main(string[] args)
{
    int x = 40;
    GetAString firstStringMethod = new GetAString(x.ToString);
    Console.WriteLine("String is" + firstStringMethod());
    // With firstStringMethod initialized to x.ToString(),
    // the above statement is equivalent to saying
    // Console.WriteLine("String is" + x.ToString());

}

-  Trong mã này, ta tạo ra delegate GetAString, và khởi tạo nó để nó tham khảo đến phương thức ToString() của một biến nguyên x .chúng ta sẽ biên dịch lỗi nếu cố gắng khởi tạo FirstStringMethod với bất kì phương thức nào có thông số vào và kiểu trả về là chuỗi.

-  1 đặc tính của delegate là an toàn kiểu ( type-safe) để thấy rằng chúng phải đảm bảo dấu ấn ( signature) của phương thức được gọi là đúng. Tuy nhiên 1 điều thú vị là, chúng không quan tâm kiểu của đối tượng phương thức là gì khi gọi hoặc thậm chí liệu rằng phương thức đó là static hay là một phương thức thể hiện.

-  Để thấy điều này ta mở rộng đoạn mã trên, dùng delegate FirstStringMethod để gọi các phương thức khác trên những đối tượng khác – 1 phương thức thể hiện và 1 phương thức tĩnh. Ta cũng dùng lại cấu trúc currency, và cấu trúc currency đã có overload riêng của nó cho phương thức ToString(). Để xem xét delegate với phương thức tĩnh ta thêm 1 phương thức tĩnh với cùng dấu ấn như currency:

struct Currency
{
    public static string GetCurrencyUnit()
    {
        return "Dollar";
    }
}

-  Bây giờ ta sử dụng thể hiện GetAString như sau:

    private delegate string GetAString();

static void Main(string[] args)
{
    int x = 40;
    GetAString firstStringMethod = new GetAString(x.ToString);
    Console.WriteLine("String is " + firstStringMethod());
    Currency balance = new Currency(34, 50);
    firstStringMethod = new GetAString(balance.ToString);
    Console.WriteLine("String is " + firstStringMethod());
    firstStringMethod = new GetAString(Currency.GetCurrencyUnit);
    Console.WriteLine("String is " + firstStringMethod());
}

-  Đoạn mã này chỉ cho ta biết làm thế nào để gọi 1 phương thức qua trung gian là delegate, đăng kí lại delegate để tham chiếu đến một phương thức khác trên 1 thể hiện khác của lớp.

-  Tuy nhiên ta vẫn chưa nắm rõ được quy trình truyền 1 delegate đến 1 phương thức khác, cũng như chưa thấy được lợi ích của delegate qua ví dụ trên. Như ta có thể gọi trực tiếp ToString() từ int hay currency mà không cần delegate. Ta cần những ví dụ phức tạp hơn để hiểu rõ delegate. Ta sẽ trình bày 2 ví dụ: ví dụ 1 đơn giản sử dụng delegate để gọi vào thao tác khác. Nó chỉ rõ làm thế nào để truyền delegate đến phương thức và cách sử dụng mảng trong delegate. Ví dụ 2 phức tạp hơn là lớp BubbleSorter,  thực thi 1 phương thức sắp xếp mảng đối tượng tăng dần. lớp này sẽ rất khó viết nếu không có delegate.

a. Ví dụ: SimpleDelegate

-   Trong ví dụ này ta sẽ tạo lớp MathOperations mà có vài phương thức static để thực thi 2 thao tác trên kiểu double, sau đó ta dùng delegate để gọi những phương thức này. Lớp như sau:

class MathsOperations
{
    public static double MultiplyByTwo(double value)
    {
        return value * 2;
    }

    public static double Square(double value)
    {
        return value * value;
    }
}

-   Sau đó ta gọi phương thức này như sau:

using System;

namespace SimpleDelegate
{
    delegate double DoubleOp(double x);

    class MainEntryPoint
    {
        static void Main()
        {
            DoubleOp[] operations =
            {
               new DoubleOp(MathsOperations.MultiplyByTwo),
               new DoubleOp(MathsOperations.Square)
            };

            for (int i = 0; i < operations.Length; i++)
            {
                Console.WriteLine("Using operations[{0}]:", i);
                ProcessAndDisplayNumber(operations[i], 2.0);
                ProcessAndDisplayNumber(operations[i], 7.94);
                ProcessAndDisplayNumber(operations[i], 1.414);
                Console.WriteLine();
            }
        }

        static void ProcessAndDisplayNumber(DoubleOp action, double value)
        {
            double result = action(value);
            Console.WriteLine(
               "Value is {0}, result of operation is {1}", value, result);
        }

    }
}

-  Trong đoạn mã này ta khởi tạo 1 mảng delegate doubleOp. Mỗi phần tử của mảng được khởi động để tham chiếu đến 1 thao tác khác được thực thi bởi lớp MathOperations. Sau đó, nó lặp xuyên suốt mảng,ứng dụng mỗi thao tác đến 3 kiểu giá trị khác nhau. Điều này minh họa cách sử dụng delegate – là có thể nhóm những phương thức lại với nhau thành mảng để sử dụng, để ta có thể gọi một vài phương thức trong vòng lặp.

-  Chỗ quan trọng trong đoạn mã là chỗ ta truyền 1 delegate vào phương thức ProcessAndDisplayNumber(), ví dụ:

    ProcessAndDisplayNumber(operations[i], 2.0);

-  Ở đây ta truyền tên của delegate, nhưng không có thông số nào cho rằng operation[i] là 1 delegate :

  • operation[i] nghĩa là ‘delegate’,nói cách khác là phương thức đại diện cho delegate.
  • operation[i](2.0) nghĩa là ‘gọi thực sự phương thức này, truyền giá trị vào trong ngoặc’.
  • Phương thức ProcessAndDisplayNumber() được định nghĩa để lấy 1 delegate như là thông số đầu tiên của nó :


    static void ProcessAndDisplayNumber(DoubleOp action, double value)

  • Sau đó khi ở trong phương thức này , ta gọi:


    double result = action(value);

  • Thể hiện delegate action được gọi và kết quả trả về được lưu trữ trong result

    chạy ví dụ ta có:

SimpleDelegate
Using operations[0]:
Value is 2, result of operation is 4
Value is 7.94, result of operation is 15.88
Value is 1.414, result of operation is 2.828

Using operations[1]:
Value is 2, result of operation is 4
Value is 7.94, result of operation is 63.0436
Value is 1.414, result of operation is 1.999396

b. Ví dụ BubleSorter

-  Sau đây ta sẽ xem 1 ví dụ cho thấy sự hữu ích của delegate. Ta sẽ tạo lớp bublesorter. Lớp này thực thi 1 phương thức tĩnh, Sort() lấy thông số đầu là 1 mảng đối tượng, và sắp xếp lại chúng tăng dần. Ví dụ để sắp xếp 1 mảng số nguyên bằng thuật toán Bubble sort :

///đây không phải là 1 phần của ví dụ
for (int i = 0; i < sortArray.Length; i++)
{
      for (int j = i + 1; j < sortArray.Length; j++)
      {
         if (sortArray[j] < sortArray[i])   // problem with this test
         {
            int temp = sortArray[i];   // swap ith and jth entries
            sortArray[i] = sortArray[j];
            sortArray[j] = temp;
         }
      }
}

-  Thuật toán này tốt cho số nguyên, nhưng ta muốn phương thức sort() sắp xếp cho mọi đối tượng, ta thấy vấn đề nằm ở dòng if(sortArray[j] < sortArray[i]) trong đoạn mã trên.bởi ta muốn so sánh 2 đối tượng trên mảng mà cái nào là lớn hơn. Chúng ta có thể sắp xếp kiểu int, nhưng làm thế nào để sắp xếp những lớp chưa biết hoặc không xác định cho đến lúc chạy. Câu trả lời là mã client, mà biết về lớp muốn sắp xếp, phải truyền 1 delegate gói trong một phương thức sẽ làm công việc so sánh.

-  Định nghĩa delegate như sau:


    delegate bool CompareOp(object lhs, object rhs);

-  Và xây dựng phương thức sort() là :


    static public void Sort(object [] sortArray, CompareOp gtMethod)

-  Phần hướng dẫn cho phương thức này sẽ nói rõ rằng gtmethod phải tham chiếu đến 1 phương thức static có 2 đối số, và trả về true nếu giá trị của đối số thứ 2 là ‘lớn hơn’ (nghĩa là năm sau trong mảng) đối số thứ nhất. Mặc dù ta có thể sử dụng delegate ở đây, nhưng cũng có thể giải quyết vấn đề bằng cách sử dụng interface. .NET xây dựng 1 interfaceIComparer cho mục đích này. Tuy nhiên, ta sử dụng delegate vì loại vấn đề này thì thường có khuynh hướng dùng delegate.

-  Sau đây là lớp bublesorter :

class BubbleSorter
{
    static public void Sort(object[] sortArray, CompareOp gtMethod)
    {
        for (int i = 0; i < sortArray.Length; i++)
        {
            for (int j = i + 1; j < sortArray.Length; j++)
            {
                if (gtMethod(sortArray[j], sortArray[i]))
                {
                    object temp = sortArray[i];
                    sortArray[i] = sortArray[j];
                    sortArray[j] = temp;
                }
            }
        }
    }
}

-  Để dùng lớp này ta cần định nghĩa 1 số lớp khác mà có thể dùng thiết lập mảng cần sắp xếp. Ví dụ công ty điện thoại có danh sách tên khách hàng, và muốn sắp danh sách theo lương.mỗi nhân viên trình bày bởi thể hiện của một lớp , Employee:

class Employee
{
    private string name;
    private decimal salary;

    public Employee(string name, decimal salary)
    {
        this.name = name;
        this.salary = salary;
    }

    public override string ToString()
    {
        return string.Format(name + ", {0:C}", salary);
    }

    public static bool RhsIsGreater(object lhs, object rhs)
    {
        Employee empLhs = (Employee)lhs;
        Employee empRhs = (Employee)rhs;
        return (empRhs.salary > empLhs.salary) ? true : false;
    }
}

-  Lưu ý để phù hợp với dấu ấn của delegate CompareOp, chúng ta phải định nghĩa RhsIsGreater trong lớp này lấy 2 đối tượng để tham khảo,hơn là tham khảo employee như là thông số.điều này có nghĩa là ta phải ép kiểu những thông số vào trong tham khảo employee để thực thi việc so sánh.

-  Bây giờ ta viết mã yêu cầu sắp xếp :

namespace Wrox.ProCSharp.AdvancedCSharp
{
    delegate bool CompareOp(object lhs, object rhs);

    class MainEntryPoint
    {
        static void Main()
        {
            Employee[] employees =
            {
               new Employee("Karli Watson", 20000),
               new Employee("Bill Gates", 10000),
               new Employee("Simon Robinson", 25000),
               new Employee("Mortimer", (decimal)1000000.38),
               new Employee("Arabel Jones", 23000),
               new Employee("Avon from 'Blake's 7'", 50000)};
            CompareOp employeeCompareOp = new CompareOp(Employee.RhsIsGreater);
            BubbleSorter.Sort(employees, employeeCompareOp);

            for (int i = 0; i < employees.Length; i++)
                Console.WriteLine(employees[i].ToString());
        }
    }
}

-  Chạy mã này sẽ thấy employees được sắp xếp theo lương .

BubbleSorter
Bill Gates, £10,000.00
Karli Watson, £20,000.00
Arabel Jones, £23,000.00
Simon Robinson, £25,000.00
Avon from 'Blake's 7', £50,000.00
Mortimer, £1,000,000.38

2.  Multicast delegate

-  Đến lúc này mỗi delegate mà chúng ta sử dụng chỉ gói ghém trong 1 phương thức đơn gọi. Gọi delegate nào thì dùng phương thức đó. Nếu ta muốn gọi nhiều hơn 1 phương thức, ta cần tạo một lời gọi tường minh xuyên suốt delegate nhiều hơn một lần. Tuy nhiên, 1 delegate có thể gói ghém nhiều hơn 1 phương thức. 1 delegate như vậy gọi là multicast delegate. nếu 1 multicast delegate được gọi, nó sẽ gọi liên tiếp những phương thức theo thứ tự. Để làm điều này, delegate phải trả về là void. Nếu ta dùng một delegate có kiểu trả về làvoid, trình biên dịch sẽ coi như đây là một multicast delegate. Xem ví dụ sau, dù cú pháp giống như trước đây nhưng nó thực sự là một multicast delegate, operations,

class MainEntryPoint
{
    static void Main()
    {
        DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo);
        operations += new DoubleOp(MathOperations.Square);
    }
}

-  Trong ví dụ trên muốn tham khảo đến 2 phương thức ta dùng mảng delegate. Ở đây, đơn giản ta chỉ thêm 2 thao tác này vào trong cùng một multicast delegate.multiccast delegate nhận toán tử + và +=. Nếu ta muốn, ta có thể mở rộng 2 dòng mã trên, có cùng cách tác động:

DoubleOp operation1 = new DoubleOp(MathOperations.MultiplyByTwo);
DoubleOp operation2 = new DoubleOp(MathOperations.Square);
DoubleOp operations = operation1 + operation2;

multicast delegate cũng biết toán tử – và -= để bỏ đi phương thức được gọi từ delegate.

-   một muticast delegate là một lớp được dẫn xuất từ System.MulticastDelegate mà lại được dẫn xuất từ System.Delegate. System.MulticastDelegate có thêm những thành phần để cho phép nối những phương thức gọi cùng với nhau vào một danh sách.

-  Minh hoạ cho sử dụng multicast delegate ta sử dụng lại ví dụ simpleDelegate biến nó thành một ví dụ mới MulticastDelegate. bởi vì ta cần delegate trả về kiểu void, ta phải viết lại những phương thức trong lớp Mathoperations, chúng sẽ trình bày kết quả thay vì trả về:

class MathOperations
{
    public static void MultiplyByTwo(double value)
    {
        double result = value * 2;
        Console.WriteLine(
           "Multiplying by 2: {0} gives {1}", value, result);
    }

    public static void Square(double value)
    {
        double result = value * value;
        Console.WriteLine("Squaring: {0} gives {1}", value, result);
    }
}

-  Để dàn xếp sự thay đổi này, ta viết lại ProcessAndDisplayNumber:

static void ProcessAndDisplayNumber(DoubleOp action, double value)
{
    Console.WriteLine("\nProcessAndDisplayNumber called with value = " + value);
    action(value);
}

-  Bây giờ thử multicast delegate ta vừa tạo :

static void Main()
{
   DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo);
   operations += new DoubleOp(MathOperations.Square);

   ProcessAndDisplayNumber(operations, 2.0);
   ProcessAndDisplayNumber(operations, 7.94);
   ProcessAndDisplayNumber(operations, 1.414);
   Console.WriteLine();
}

-  Bây giờ mỗi lần ProcessAndDisplayNumber được gọi, nó sẽ trình bày 1 thông điệp để báo rằng nó được gọi câu lệnh sau: action(value);

-  Sẽ làm cho mỗi phương thức gọi trong thể hiện delegate action được gọi liên tiếp nhau.

-   Kết quả :

MulticastDelegate

ProcessAndDisplayNumber called with value = 2
Multiplying by 2: 2 gives 4
Squaring: 2 gives 4

ProcessAndDisplayNumber called with value = 7.94
Multiplying by 2: 7.94 gives 15.88
Squaring: 7.94 gives 63.0436

ProcessAndDisplayNumber called with value = 1.414
Multiplying by 2: 1.414 gives 2.828
Squaring: 1.414 gives 1.999396

-  Nếu dùng multicast delegate , ta nên nhận thức đến thứ tự phương thức được nối với nhau trong cùng một delegate sẽ được gọi là không xác định. Do đó ta nên tránh viết mã mà những phương thức được gọi liên hệ với nhau theo một thứ tự cụ thể.

(Tham khảo Professional C# 3nd editor tại Wrox.com)

Nguồn: http://thanhcuong.wordpress.com

 

Nhãn: , ,

Lấy danh sách liên hệ từ gmail bằng C# – Get Gmail contact list using C#

Việc lấy danh sách liên hệ từ gmail có rất nhiều cách, đơn giản nhất là sử dụng tính năng export contacts được tích hợp sẵn trong gmail. Nhưng  với ngôn ngữ C# thì làm thể nào để chúng ta lấy ra danh sách liên hệ từ gmail. Điều này khá thú vị đúng không? Và Google đã cung cấp cho chúng ta các API để giúp chúng ta thực hiện những điều nói trên.

1. Download và cài đặt Google data APIs cho .NET

-  Đầu tiên chúng ta download Google Data APIs cho .NET tại đây. Sau đó tiến hành cài đặt bình thường.

image

-  Mặc định chương trình sẽ được cài vào C:\Program Files\Google\Google Data API SDK.

2. Sử dụng Google Data APIs trong .NET

-  Khi cài Google Data APIs thì theo mặc định đường dẫn chứa các file *.dll sử dụng khi lập trình sẽ nằm trong đường dẫn: C:\Program Files\Google\Google Data API SDK\Redist như: Google.GData.Client.dll, Google.GData.CodeSearch.dll, Google.GData.Contacts.dll…

-  Để sử dụng những APIs mà google đã cung cấp nói trên trong C#. Chúng ta tiến hành tạo project C# một cách bình thường (Lưu ý sủ dụng .NET 2.0 để tránh tình trạng báo lỗi vì Google APIs hình như chưa hỗ trợ cho .NET 4.0)

image

-  Sau đó add các file .dll cần thiết mà Google cung cấp để sử dụng trong chương trình này: Google.GData.Client.dll,  Google.GData.Contacts.dll, Google.Gdata.Extension.dll. Bằng cách: Click chuột phải vào project trong cửa sổ solution explorer chọn Add Reference

image

  Trong cửa sổ hiện ra chọn tab Browse rồi duyệt tới đường dẫn đã cài Google APIs (mặc định là C:\Program Files\Google\Google Data API SDK\Redist). Rồi chọn 3 file .dll nói trên sau đó Ok.

image

Sau khi thực hiện tao tác add reference trên thì trong thanh solution explorer sẽ xuất hiện các file .dll đã add vào reference như hình bên dưới.

image

-  Bây giờ chúng ta có thể sử dụng các APIs trong các thư viện vừa add vào để viết code cho chương trình.  Trong code để sử dụng các APIs trên chúng ta cần khai báo using:

using Google.GData.Client;
using Google.Contacts;



3. Source code chương trình lấy danh sách liên hệ từ Gmail

-  Chương trình được phân làm 2 lớp Form: 1 Form dùng để đăng nhập (class Form1.cs) và 1 Form để hiển thị danh sách liên hệ (class Contacts.cs).

image

image

 

 

 

 

 

 

 

 

– Source code của Class Form1.cs như sau:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using Google.GData.Client; using Google.Contacts; using System.Windows.Forms; namespace Get_gmail_contacts { public partial class Form1 : Form { public Form1() { InitializeComponent(); txtPass.PasswordChar = '*'; } private Service service; private string authToken; public Form1(Service serviceToUse) { InitializeComponent(); service = serviceToUse; } public Form1(Service serviceToUse, string username) { InitializeComponent(); service = serviceToUse; txtUser.Text = username; } public string AuthenticationToken { get { return authToken; } } public bool RememberAuthentication { get { return cbToken.Visible; } set { cbToken.Visible = value; } } public string user { get { return txtUser.Text; } } private void btnCancel_Click(object sender, EventArgs e) { authToken = null; this.Close(); } private void btnLogin_Click(object sender, EventArgs e) { this.Hide(); Contacts fC = new Contacts(); fC.setText("GoogleTest", txtUser.Text,txtPass.Text); fC.Show(); } private void txtUser_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { btnLogin_Click(null, null); } } private void txtPass_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { btnLogin_Click(null, null); } } } }

-  Và class Contacts.cs như sau:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Google.GData.Client; using Google.Contacts; using Google.GData.Extensions; using Google.GData.Contacts; namespace Get_gmail_contacts { public partial class Contacts : Form { public Contacts() { InitializeComponent(); } public List<GoogleContacts> list; public List<GoogleContacts> GetGoogleContacts(string appName, string un, string pwd) { List<GoogleContacts> contactList = new List<GoogleContacts>(); RequestSettings settings = new RequestSettings(appName, un, pwd); settings.AutoPaging = true; ContactsRequest request = new ContactsRequest(settings); Feed<Contact> feed = request.GetContacts(); foreach (Contact contact in feed.Entries) { GoogleContacts c = new GoogleContacts(); c.title = string.IsNullOrEmpty(contact.Title) ? "Chua dat ten" : contact.Title; c.im = contact.IMs.Count == 0 ? " " : contact.IMs[0].Address; c.email = contact.Emails.Count == 0 ? " " : contact.Emails[0].Address; contactList.Add(c); } return contactList; } public void addContactsToListBox(List<GoogleContacts> contactList) { lbName.Text = "S? liên h? trong danh sách: " + contactList.Count.ToString(); foreach (GoogleContacts contact in contactList) { lbxContacts.Items.Add(contact.title + " - " + contact.email + " - " + contact.im); } } public void setText(string a, string b, string c) { list = GetGoogleContacts(a, b, c); } private void Contacts_Load(object sender, EventArgs e) { addContactsToListBox(list); } } public class GoogleContacts { public string title { get; set; } public string email { get; set; } public string im { get; set; } } }

 

– Tải Source Code Demo chương trình lấy danh sách liên hệ gmail viết trên Visual studio 2010 bằng C#. (Click here to download demo source code Get Gmail Contact List Program using C#).

Chúc thành công!

(Tham khảo Google Data APIs)

Nguồn: http://thanhcuong.wordpress.com

 

Nhãn: , , , , , ,