Thứ Ba, 3 tháng 3, 2009

Làm thế nào để Declare, Instantiate, và sử dụng là một Delegate

Trong C# 1.0 và trở về sau, các delegate có thể được kê khai như trong ví dụ sau.

// Declare a delegate.
delegate void Del(string str);

// Declare a method with the same signature as the delegate.
static void Notify(string name)
{
          Console.WriteLine("Notification received for: {0}", name);
}

// Create an instance of the delegate.
Del del1 = new Del(Notify);

C# 2.0 cung cấp một cách đơn giản để viết delegate trước đó, như trong ví dụ sau.

// C# 2.0 provides a simpler way to declare an instance of Del.
Del del2 = Notify;

Trong C# 2.0 và sau, nó cũng có thể sử dụng một method anonymous để khai báo và khởi tạo là một delegate, như trong ví dụ sau.

// Instantiate Del by using an anonymous method.
Del del3 = delegate(string name) { Console.WriteLine("Notification received for: {0}", name); };

Trong C# 3.0 và sau, các delegate cũng có thể được khai báo và khởi tạo bằng cách sử dụng là một biểu thức lambda, như trong ví dụ sau.

// Instantiate Del by using a lambda expression.
Del del4 = name => { Console.WriteLine("Notification received for: {0}", name); };

Việc sử dụng các các delegate phát huy tốt chức năng tách giữa các cơ sở dữ liệu mã hiệu sách và các khách hàng. Mã khách hàng không có kiến thức về cách các cuốn sách được lưu trữ hoặc làm thế nào mã hiệu sách tìm thấy cuốn sách bìa mềm. Các mã hiệu sách không có kiến thức về những gì xử lý được thực hiện trên những cuốn sách bìa mềm sau khi nó tìm thấy chúng.

// A set of classes for handling a bookstore:
namespace Bookstore
{
       using System.Collections;

       // Describes a book in the book list:
       public struct Book
       {
               public string Title; // Title of the book.
               public string Author; // Author of the book.
               public decimal Price; // Price of the book.
               public bool Paperback; // Is it paperback?

               public Book(string title, string author, decimal price, bool paperBack)
               {
                      Title = title;
                      Author = author;
                      Price = price;
                      Paperback = paperBack;
               }
        }

        // Declare a delegate type for processing a book:
        public delegate void ProcessBookDelegate(Book book);

        // Maintains a book database.
        public class BookDB
        {
               // List of all books in the database:
               ArrayList list = new ArrayList();

               // Add a book to the database:
               public void AddBook(string title, string author, decimal price, bool paperBack)
               {
                      list.Add(new Book(title, author, price, paperBack));
               }

               // Call a passed-in delegate on each paperback book to process it:
               public void ProcessPaperbackBooks(ProcessBookDelegate processBook)
               {
                      foreach (Book b in list)
                      {
                             if (b.Paperback)
                                   // Calling the delegate:
                                   processBook(b);
                      }
               }
        }
}

// Using the Bookstore classes:
namespace BookTestClient
{
       using Bookstore;

       // Class to total and average prices of books:
       class PriceTotaller
       {
               int countBooks = 0;
               decimal priceBooks = 0.0m;

               internal void AddBookToTotal(Book book)
               {
                       countBooks += 1;
                       priceBooks += book.Price;
               }

               internal decimal AveragePrice()
               {
                       return priceBooks / countBooks;
               }
        }

         // Cla ss to test the book database:
         class TestBookDB
         {
                // Print the title of the book.
                static void PrintTitle(Book b)
                {
                         System.Console.WriteLine(" {0}", b.Title);
                }

                // Execution starts here.
                static void Main()
                {
                           BookDB bookDB = new BookDB();
          
                           // Initialize the database with some books:
                           AddBooks(bookDB);
                           // Print all the titles of paperbacks:
                           System.Console.WriteLine("Paperback Book Titles:");

                           // Create a new delegate object associated with the static
                           // method Test.PrintTitle:
                           bookDB.ProcessPaperbackBooks(PrintTitle);
                           // Get the average price of a paperback by using
                           // a PriceTotaller object:
                           PriceTotaller totaller = new PriceTotaller();
                           // Create a new delegate object associated with the nonstatic
                           // method AddBookToTotal on the object totaller:
                           bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);

                           System.Console.WriteLine("Average Paperback Book Price: ${0:#.##}",
                           totaller.AveragePrice());
                  }

                 // Initialize the book database with some test books:
                 static void AddBooks(BookDB bookDB)
                 {
                         bookDB.AddBook("The C Programming Language", 
                                  "Brian W. Kernighan and Dennis M. Ritchie", 19.95m, true);
                         bookDB.AddBook("The Unicode Standard 2.0", 
                                  "The Unicode Consortium", 39.95m, true);
                         bookDB.AddBook("The MS-DOS Encyclopedia", 
                                  "Ray Duncan", 129.95m, false);
                         bookDB.AddBook("Dogbert's Clues for the Clueless", 
                                  "Scott Adams", 12.00m, true);
                  }
         }
}
/* Output:
Paperback Book Titles:
The C Programming Language
The Unicode Standard 2.0
Dogbert's Clues for the Clueless
Average Paperback Book Price: $23.97
*/

DangTrung.

Classes và cấu trúc

Các lớp học và cấu trúc là hai trong số các cấu trúc cơ bản của hệ thống kiểu thông dụng trong các .NET Framework. Mỗi bản chất là một cấu trúc dữ liệu mà gói gọn một tập hợp các dữ liệu và hành vi thuộc về nhau như một đơn vị logic. Các dữ liệu và hành vi là những thành viên của lớp hoặc cấu trúc, và chúng bao gồm các phương pháp, thuộc tính, và các sự kiện, vân vân, được liệt kê sau trong chủ đề này.

Một class khi khai báo cấu trúc giống như một kế hoạch chi tiết được sử dụng để tạo ra các trường hợp hoặc các đối tượng lúc thực thi. Nếu bạn định nghĩa một class hoặc cấu trúc được gọi là Person, Person là tên của kiểu. Nếu bạn khai báo và khởi tạo một biến p của Person, p được cho là một đối tượng hoặc thể hiện của Person. Nhiều trường hợp của các kiểu cùng một người có thể được tạo ra, và mỗi trường hợp có thể có giá trị khác nhau trong thuộc tính và các trường nó.

Lớp là một kiểu tham chiếu. Khi một đối tượng của lớp được tạo ra, biến mà đối tượng được giao nắm giữ chỉ là một tham chiếu đến bộ nhớ. Khi các tham chiếu đối tượng được gán cho một biến mới, biến mới liên quan đến các đối tượng ban đầu. Thay đổi được thực hiện thông qua một biến được phản ánh trong các biến khác, bởi vì cả hai đều đề cập đến cùng một dữ liệu.

Struct A là một kiểu giá trị. Khi cấu trúc được tạo ra, biến mà cấu trúc được phân công giữ cấu trúc của dữ liệu thực tế. Khi cấu trúc lại được giao cho một biến mới, đó là sao chép. Các biến mới và thay đổi bản gốc do đó có hai bản sao riêng biệt của cùng dữ liệu. Thay đổi được thực hiện cho một bản sao không ảnh hưởng đến các bản sao khác.

Nhìn chung, các lớp học được sử dụng để mô hình hành vi phức tạp hơn, hoặc dữ liệu được dự định được sửa đổi sau khi một đối tượng lớp được tạo ra. Struct phù hợp nhất để cấu trúc dữ liệu nhỏ có chứa chủ yếu là dữ liệu mà không có ý định được sửa đổi sau khi các cấu trúc được tạo ra.

Trong ví dụ sau đây, MyCustomClass được xác định với ba thành viên ở cấp cao nhất của namespace ProgrammingGuide. Một cá thể (object) của MyCustomClass được tạo ra trong các method chính trong chương trình class, và method của object và thuộc tính được truy cập bằng cách sử dụng ký hiệu dấu chấm.

namespace ProgrammingGuide
{
        // Class definition.
        public class MyCustomClass
        {
               // Class members: Property.
               public int Number { get; set; }

               // Method.
               public int Multiply(int num)
               {
                        return num * Number;
               }

               // Instance Constructor.
               public MyCustomClass()
               {
                       Number = 0;
               }
         }
         // Another class definition. This one contains
         // the Main method, the entry point for the program.
         class Program
         {
                static void Main(string[] args)
                {
                        // Create an object of type MyCustomClass.
                        MyCustomClass myClass = new MyCustomClass();

                        // Set the value of a public property.
                        myClass.Number = 27;

                        // Call a public method.
                        int result = myClass.Multiply(4);
                }
        }
}

Thành viên

Tất cả các method, các trường, constants, tài sản, và các sự kiện phải được khai báo trong phạm vi kiểu là một, chúng được gọi là các thành viên của lớp học hoặc struct. Trong C #, không có biến toàn cục hoặc các phương pháp như có trong một số ngôn ngữ khác. Ngay cả chỉ mục của chương trình, phương pháp chính, phải được khai báo trong một lớp hoặc Struct. Danh sách sau đây bao gồm tất cả các loại của các thành viên có thể sẽ được kê khai trong một lớp học hoặc Struct.
  • Fields
  • Constants
  • Properties
  • Methods
  • Constructors
  • Destructors
  • Events
  • Indexers
  • Operators
  • Nested Types

DangTrung.

Thứ Hai, 2 tháng 3, 2009

ASP.NET Ajax : Cách Gọi ASP NET MVC Controller Actions

ASP.NET MVC cung cấp một framework để xây dựng các ứng dụng theo Model-View-Controller (MVC) pattern. Mô hình này đại diện cho dữ liệu sử dụng trong các ứng dụng, các Controller chịu trách nhiệm cho hành động đó xảy ra và View là đại diện cho giao diện người dùng mà người dùng cuối tương tác trong ứng dụng. The ASP.NET AJAX Thư viện có thể đóng một vai trò quan trọng trong các ứng dụng ASP.NET MVC khi một trang cần được Ajax bật. Hướng dẫn này sẽ thảo luận làm thế nào để trở về JSON (JavaScript Object Notation) kết quả từ một Controller Actions quá trình và trong vòng một trang view. Các bước thảo luận bao gồm:
  • Tạo một dự án ASP.NET MVC
  • Tạo một JsonResult Controller Action
  • Gọi một Controller Action và Kết quả Binding
Bước 1: Tạo một dự án ASP.NET MVC

ASP.NET MVC framework không được bao gồm trong Visual Studio 2008 theo mặc định, nhưng có thể được tải về và cài đặt từ http://www.asp.net/mvc. Visual Studio 2010 đi kèm với ASP.NET MVC ra khỏi hộp. Để tạo một ASP.NET mới MVC dự án chọn File | New Project và chọn ASP.NET MVC Web Application từ mẫu. Sau khi tạo dự án bạn sẽ thấy một số các thư mục trong dự án bao gồm một lý, kiểu xe và thư mục xem.

Bước 2: Tạo một JsonResult điều khiển hành động

Mở rộng các thư mục Models và thêm một class mới vào project có tên là Customer có các thuộc tính sau:

public class Customer
{
      public int CustomerID { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public int Age { get; set; }
}

Mở rộng thư mục Controllers và mở các class tên là HomeController.cs trong cửa sổ soạn code. Chú ý rằng nó có một vài hành động được xác định theo mặc định. Nhập khẩu các không gian tên được chỉ định cho các Customer class sử dụng hoặc tuyên bố nhập khẩu và sau đó thêm các action sau đây để trả về một List.

public JsonResult GetCustomers()
{
        List custs = new List
       {
             new Customer
             {
                  CustomerID = 1,
                  FirstName = "John",
                  LastName = "Doe",
                 Age = 50
              },
             new Customer
            {
                    CustomerID = 2,
                  FirstName = "Jane",
                  LastName = "Doe",
                  Age = 47
            }
       };
       return Json(custs);
}


ASP.NET MVC Controller actions thường được trả lại một loại ActionResult. Tuy nhiên, bởi vì actions này trở về dữ liệu JSON một loại JsonResult trở lại được xác định. Khi đối tượng List được tạo ra nó được chuyển thành dữ liệu JSON bằng cách sử dụng phương pháp xây dựng trong JSON.

Bước 3: Kêu gọi một hành động điều khiển và Kết quả Binding

Mở rộng thư mục Views/Home và mở file index.aspx trong cửa sổ soạn code. Để sử dụng chức năng trong Script ASP.NET Script Library có thể được dùng để nạp object script và các tập lệnh MicrosoftAjaxWebServices.js. Thêm dòng sau vào trong kiểm soát nội dung rằng có một giá trị ContentPlaceHolderID của "MainContent":




Điều quan trọng cần lưu ý là lệnh được dùng nhiều lần trong một ứng dụng ASP.NET MVC có thể được tải tại của ứng dụng trang Master để bảo trì đơn giản hóa như trái ngược với tải chúng trong một Xem cụ thể.

Bây giờ mà các thành phần DataView được tạo ra mẫu mà nó gắn với nhu cầu để được tạo ra. Thêm sau mẫu mã dưới đây đóng yếu tố :

 
        {{FirstName}} {{LastName}}
       



DangTrung

Làm thế nào để truy cập một Class Collection với foreach

Các ví dụ mã sau minh họa làm thế nào để viết một lớp tổng quát mà có thể được sử dụng với foreach. Lớp học là một tokenizer chuỗi, tương tự như chức năng strtok_s C run-time.

Trong ví dụ sau đây, Tokens chia các câu "Đây là một câu ví dụ." vào thẻ bằng cách sử dụng '' và '-' là dấu phân cách, và liệt kê những thẻ bài bằng foreach:

Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});
foreach (string item in f)
{
      System.Console.WriteLine(item);
}

Trong nội bộ, Tokens sử dụng một mảng, mà thực hiện IEnumerator và IEnumerable chính nó. Ví dụ mã có thể đã sử dụng phương pháp liệt kê của mảng như là của riêng nó, nhưng mà có thể đã thất bại nhằm mục đích của ví dụ này.

Trong C#, nó không phải là hoàn toàn cần thiết để một class collections để kế thừa từ IEnumerable và IEnumerator để tương thích với foreach. Khi lớp có GetEnumerator yêu cầu, MoveNext, Reset, và các thành viên hiện tại, nó sẽ làm việc với foreach. Bỏ qua các interface có lợi thế là cho phép bạn xác định kiểu trả về của hiện tại để được nhiều hơn so với đối tượng cụ thể, cung cấp kiểu an toàn.

Ví dụ, bắt đầu với ví dụ mã trước đó trong chủ đề này, thay đổi những dòng này:

// No longer inherits from IEnumerable:
public class Tokens
// Doesn't return an IEnumerator:
public TokenEnumerator GetEnumerator()
// No longer inherits from IEnumerator:
public class TokenEnumerator
// Type-safe: returns string, not object:
public string Current

Bây giờ, bởi vì trả về một chuỗi hiện tại, các trình biên dịch có thể phát hiện khi một kiểu không tương thích được sử dụng trong một câu lệnh foreach:

// Error: cannot convert string to int:
foreach (int item in f)

Những bất lợi của IEnumerable và IEnumerator bỏ qua là các class collections không còn tương thích với các câu lệnh foreach, hoặc tương đương, của các ngôn ngữ khác ngôn ngữ thông dụng khi chạy tương thích.

Bạn có thể có tốt nhất của cả hai thế giới, kiểu an toàn trong C# và khả năng tương tác với các ngôn ngữ khác ngôn ngữ phổ biến thời gian chạy tương thích, do thừa kế từ IEnumerable và IEnumerator và sử dụng giao diện thực hiện rõ ràng như thể hiện trong ví dụ sau đây.

using System.Collections;


// Declare the Tokens class:
public class Tokens : IEnumerable
{
       private string[] elements;


       Tokens(string source, char[] delimiters)
       {
               // Parse the string into tokens:
               elements = source.Split(delimiters);
       }


       // IEnumerable Interface Implementation:
       // Declaration of the GetEnumerator() method
       // required by IEnumerable
       public IEnumerator GetEnumerator()
       {
               return new TokenEnumerator(this);
        }


        // Inner class implements IEnumerator interface:
        private class TokenEnumerator : IEnumerator
        {
               private int position = -1;
               private Tokens t;


               public TokenEnumerator(Tokens t)
               {
                      this.t = t;
               }


               // Declare the MoveNext method required by IEnumerator:
               public bool MoveNext()
               {
                     if (position < t.elements.Length - 1)
                     {
                             position++;
                             return true;
                     }
                     else
                     {
                             return false ;
                     }
               }
               // Declare the Reset method required by IEnumerator:
               public void Reset()
               {
                     position = -1;
               }


               // Declare the Current property required by IEnumerator:
               public object Current
               {
                      get
                      {
                             return t.elements[position];
                      }
                }
          }
          // Test Tokens, TokenEnumerator
          static void Main()
          {
                // Testing Tokens by breaking the string into tokens:
                Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});
  
                foreach (string item in f)
                {
                           System.Console.WriteLine(item);
                }
         }
}
/* Output:
This
is
a
sample
sentence.
*/

DangTrung.

Collection Classes

.NET Framework cung cấp các classes chuyên dùng cho việc lưu trữ dữ liệu và phục hồi. Các classes này cung cấp hỗ trợ cho stacks, queues, lists, và HashTable. Hầu hết classes collection thực hiện tương tự các interfaces, và các interfaces này có thể được thừa kế để tạo ra các classes collection mới phù hợp với nhu cầu lưu trữ dữ liệu chuyên sâu hơn.

CHÚ Ý : Các ứng dụng hướng phiên bản 2.0 và sau này của NET Framework. nên sử dụng các classes collection Thuộc trong namespace System.Collections.Generic, cung cấp nhiều kiểu an toàn và hiệu quả hơn so với counterparts của họ không tổng quát.

ArrayList list = new ArrayList();
list.Add(10);
list.Add(20);

Tổng quan Collection Classes :

Collections có các thuộc tính sau :
  • Collection các classes được định nghĩa như là một phần của namespace System.Collections hoặc System.Collections.Generic.
  • Hầu hết các classes collection xuất phát từ interface ICollection, IComparer, IEnumerable, IList, IDictionary, và IDictionaryEnumerator và tương đương tổng quát của họ.
  • Collection Classe cung cấp an toàn và trong một số trường hợp có thể cung cấp hiệu suất tốt hơn, đặc biệt là khi họ lưu trữ giá trị các loại.

Collections và Cấu trúc dữ liệu :
  • Chặt chẽ dữ liệu liên quan có thể được xử lý hiệu quả hơn khi được nhóm lại với nhau thành một bộ sưu tập. Thay vì viết mã riêng biệt để xử lý các đối tượng riêng biệt, bạn có thể sử dụng cùng một mã để xử lý tất cả các yếu tố của một bộ sưu tập.
  • Để quản lý một bộ sưu tập, sử dụng lớp System.Array và các lớp trong System.Collections, System.Collections.Generic, và các không gian tên System.Collections.Concurrent để thêm, xóa, và sửa đổi hoặc các yếu tố cá nhân hoặc một loạt các yếu tố trong bộ sưu tập. Một bộ sưu tập toàn bộ thậm chí có thể được sao chép vào bộ sưu tập khác.
  • Một số lớp học System.Collections có khả năng phân loại, và hầu hết được lập chỉ mục. Quản lý bộ nhớ được xử lý tự động, và năng lực của các bộ sưu tập được mở rộng theo yêu cầu. Đồng bộ hóa cung cấp an toàn đề khi truy cập vào các thành viên của bộ sưu tập. Một số lớp học System.Collections có thể tạo ra loại giấy gói mà làm cho bộ sưu tập chỉ đọc hoặc kích thước cố định. Bất kỳ lớp System.Collections có thể tạo ra điều tra riêng của mình mà làm cho nó dễ dàng để chuyển đổi thông qua các yếu tố.

Chủ Nhật, 1 tháng 3, 2009

ASP.NET Ajax : Cách Gọi WCF Web Services

WCF (Windows Communication Framework) cung cấp dữ liệu một cách linh hoạt đến các ứng dụng Ajax. Hướng dẫn này cung cấp step-by-step xem cách WCF có thể được sử dụng với ASP.NET Ajax Library lấy dữ liệu từ services và gắn nó vào hệ thống điều khiển bằng cách sử dụng các DataView component và template. Từng bước được thực hiện bao gồm:
  • Tạo một WCF Services
  • Loading Scripts Bắt buộc
  • Gọi một WCF Services sử dụng DataView
Bước 1: Tạo một WCF Service

Để tạo một Ajax-enabled WCF Service, kích chuột phải vào một dự án ứng dụng web hay Website trong Visual Studio và chọn Add New Item. Chọn AJAX-enabled WCF Service mẫu như trong hình 1.


Hình 1. Thêm một Ajax-enabled WCF Service vào một Visual Studio ứng dụng web hay project Website.

Sau khi Ajax-enabled WCF Service được tạo ra một hoạt động có thể được thêm tùy chỉnh trả về dữ liệu đến các Ajax application. Các code sau đây cho thấy cách một danh sách các Customer objects có thể được trả lại từ một hoạt động service:

[ServiceContract(Namespace = "http://www.mycompany.com/MyAjaxService")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyAjaxService
{
        [OperationContract]
        public List GetCustomers(int numberToFetch)
        {
                using (NorthwindDataContext context = new NorthwindDataContext())
               {
                      return context.Customers.Take(numberToFetch).ToList();
               }
         }
}

Bước 2: Loading Scripts Bắt buộc

The ASP.NET AJAX Thư viện cung cấp một thành phần DataView có thể được sử dụng để lấy dữ liệu từ một dịch vụ WCF và gắn nó vào một bản mẫu. Để tải tập lệnh được yêu cầu của các thành phần DataView bộ nạp Script có thể được sử dụng:


Bước 3: Kêu gọi một WCF Service sử dụng DataView

Các thành phần DataView có thể được dùng để gọi một dịch vụ web với một số tiền tối thiểu của mã. Để tạo một DataView Sys.create.dataView dụ sử dụng và vượt qua các bản mẫu để ràng buộc vào cũng như các tham số xác định các dịch vụ WCF để gọi. URI dịch vụ và hoạt động để gọi có thể được xác định bằng cách sử dụng dataProvider và các thông số fetchOperation như được hiển thị tiếp theo:

Sys.require([Sys.components.dataView, Sys.scripts.WebServices], function() {
      Sys.create.dataView("#CustomerView",
     {
             dataProvider: "/Services/MyAjaxService.svc",
             fetchOperation: "GetCustomers",
             autoFetch: true,
             fetchParameters: {numberToFetch: '10'},
             itemRendered: CustomerRendered
      });

     function CustomerRendered(dataView, ctx) {
           Sys.bind(Sys.get("li", ctx), "innerHTML", ctx.dataItem, "ContactName");
     }
});

Mã này kêu gọi các hoạt động GetCustomers ngày MyAjaxService.svc và vượt qua giá trị là 10 cho tham số numberToFetch. Bằng cách đặt các dịch vụ bất động sản autoFetch đúng sẽ được gọi là tự động khi tải trang. Sau khi trở về dữ liệu từ các dịch vụ WCF chức năng CustomerRendered sẽ được gọi là mỗi dòng dữ liệu là bị ràng buộc vào một khuôn mẫu được đặt tên CustomerView. CustomerRendered liên kết với các tài sản contactname của mỗi dòng dữ liệu đến một phần tử
  • . Các CustomerView mẫu được hiển thị tiếp theo:

          
                 
  •        

    Các DataView component và các thông số của nó có liên quan cũng có thể được định nghĩa trực tiếp trên một mẫu như sau:

       
           
              
              
              
           
           
               
                     dataview:dataprovider="/Services/MyAjaxService.svc"
                     dataview:fetchParameters="{{ {numberToFetch: 10} }}"
                     dataview:fetchoperation="GetCustomers">
                   
                        
  • {{ContactName}}
  •                
              
         

    Mã này bắt đầu bằng cách xác định một "dataview" các yếu tố với giá trị là "javascript: Sys.UI.DataView". Một ví dụ của các thành phần DataView được tạo ra như là tải trang bằng cách gắn các không gian tên vừa được định nghĩa dataview cho mẫu bằng cách sử dụngsys:attach="dataview". Tham số được sử dụng bởi các thành phần DataView được định nghĩa trực tiếp trên mẫu của
    tố và tiền tố với "dataview" tiền tố không gian tên.

    Chúc bạn thành công.
    DangTrung.

    Cấu hình log4j với Xml file

    Chúng tôi cũng có thể sử dụng file XML để cấu hình log4j. Trong ví dụ trước chúng ta đã làm thế nào, chúng ta sử dụng các file properties, mọi thứ vẫn giữ nguyên ngoại trừ việc chúng tôi sử dụng các file XML ở đây.

    Các mã sau đây cho thấy các file log4j.properties chúng tôi sử dụng trong ví dụ trước.

    log4j.rootLogger=DEBUG, CA
    log4j.appender.CA=org.apache.log4j.ConsoleAppender
    log4j.appender.CA.layout=org.apache.log4j.PatternLayout
    log4j.appender.CA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n


    Để cấu hình file log4j.xml bằng cách chúng ta sử dụng method DOMConfigurator.configure().

    DangTrung.

    Sử dụng nhiều Appender trong Log4j

    Trong ví dụ này, bạn sẽ thấy làm thế nào để tạo ra một console và file appender rồi thêm nó vào rootLogger này.

    Các tập tin log4j.properties được hiển thị dưới đây.

    log4j.rootLogger=DEBUG, CA, FA

    #Console Appender
    log4j.appender.CA=org.apache.log4j.ConsoleAppender
    log4j.appender.CA.layout=org.apache.log4j.PatternLayout
    log4j.appender.CA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

    #File Appender
    log4j.appender.FA=org.apache.log4j.FileAppender
    log4j.appender.FA.File=sample.log
    log4j.appender.FA.layout=org.apache.log4j.PatternLayout
    log4j.appender.FA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

    # Set the logger level of File Appender to WARN
    log4j.appender.FA.Threshold = WARN

    Ở đây chúng ta tạo ra hai appenders ConsoleAppender và FileAppender. Bạn cần phải thiết lập các thuộc tính tập tin của FileAppender với tên file log, ở đây tôi dùng tên file là sample.log. Thêm FileAppender(FA) và các ConsoleAppender(CA) cho rootLogger.

    Bạn cũng có thể thiết lập mức độ logger cho mỗi appender riêng. Ở đây mức độ FileAppender logger được thiết lập để WARN.

    Kết quả tôi có :



    DangTrung.

    Cấu hình Log4j sử dụng file properties

    Log4j thường là được cấu hình bằng cách sử dụng một tập tin properties hoặc file xml bên ngoài. Vì vậy, một khi các báo cáo log được đặt ra bạn có thể dễ dàng kiểm soát chúng bằng cách sử dụng các file cấu hình bên ngoài mà không sửa đổi mã nguồn. Bây giờ chúng ta hãy xem cách bạn có thể có được log giống như ví dụ trên bằng cách sử dụng tập tin cấu hình properties.

    Ba thành phần chính bạn cần cấu hình để có được cùng một kết quả là các logger, appender và layout. Các đối tượng logger là một trong đó được sử dụng để log tin nhắn, appender là một trong đó quy định các điểm đến đầu ra giống như giao diện điều khiển hoặc một tập tin và layout là một trong đó xác định định dạng mà trong đó các thông điệp log được lưu lại.

    Khi bạn cấu hình bằng cách sử dụng method BasicConfigurator.configure() mặc định nó sử dụng ConsoleAppender và PatternLayout cho tất cả các logger.

    Các cấu hình dưới đây tạo ra kết quả tương tự như các method BasicConfigurator.configure().

    log4j.rootLogger=DEBUG, CA
    log4j.appender.CA=org.apache.log4j.ConsoleAppender

    log4j.appender.CA.layout=org.apache.log4j.PatternLayout
    log4j.appender.CA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

    RootLogger là một trong những hệ thống phân cấp logger. Ở đây chúng ta thiết lập mức độ của nó cho DEBUG và thêm vào console appender (CA) cho nó. Các appender console có thể có tên tùy ý, ở đây tên của nó là CA.

    Bạn cần phải tạo một appender như được hiển thị và thiết lập layout của nó để PatternLayout. PatternLayout ConversionPattern này sử dụng để định dạng tin nhắn. Để biết thêm về các định dạng tùy chọn khác nhau bạn có thể tham khảo tài liệu. (PatternLayout)


    Bạn cần phải sử dụng PropertyConfigurator.configure () để cấu hình log4j bằng cách sử dụng một tập tin properties. Log4j nên được cấu hình chỉ một lần cho toàn bộ ứng dụng.

    Khi bạn thực hiện ví dụ đầu ra dưới đây sẽ được hiển thị trên console.

    Kể từ khi cấp rootLogger được thiết lập để DEBUG tất cả các tin nhắn được hiển thị.

    Mức log4j theo trình tự dưới đây.
    • DEBUG
    • INFO
    • WARN
    • ERROR
    • FATAL
    Nếu bạn thiết lập mức độ rootLogger để cảnh báo thì chỉ có Warn, ERROR và FATAL mức độ tin nhắn sẽ được hiển thị và phần còn lại sẽ bị bỏ.


    log4j.rootLogger=WARN, CA

    DangTrung.

    Single Dimensional Arrays

    Bạn có thể khai báo một mảng một chiều của năm số nguyên như trong ví dụ sau đây:

    int[] array = new int[5];

    Mảng này chứa các yếu tố từ mảng [0] đến mảng [4]. Toán tử mới được sử dụng để tạo ra các mảng và khởi tạo các phần tử mảng để giá trị mặc định của họ. Trong ví dụ này, tất cả các phần tử mảng được khởi tạo bằng không.

    Một mảng mà lưu trữ chuỗi các phần tử có thể được khai báo trong cùng một cách. Ví dụ:

    string[] stringArray = new string[6];

    Nó có thể khởi tạo một mảng khi khai báo, trong trường hợp này, bộ ghi rõ thứ hạng là không cần thiết vì nó đã được cung cấp bởi số phần tử trong danh sách khởi tạo. Ví dụ:

    int[] array1 = new int[] { 1, 3, 5, 7, 9 };

    Một mảng chuỗi có thể được khởi tạo trong cùng một cách. Sau đây là một khai báo của một mảng chuỗi trong đó mỗi phần tử mảng được khởi tạo bởi một tên của một ngày:

    string[] weekDays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

    Khi bạn khởi tạo một mảng khi khai báo, bạn có thể sử dụng các phím tắt sau đây:

    int[] array2 = { 1, 3, 5, 7, 9 };
    string[] weekDays2 = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

    Nó có thể khai báo một biến mảng mà không cần khởi động, nhưng bạn phải sử dụng toán tử mới khi bạn chỉ định một mảng đến biến này. Ví dụ:

    int[] array3;
    array3 = new int[] { 1, 3, 5, 7, 9 }; // OK
    //array3 = {1, 3, 5, 7, 9}; // Error

    Xem xét các khái báo mảng sau đây:

    SomeType[] array4 = new SomeType[10];

    DangTrung.

    Truyền các mảng như là tham số

    Mảng có thể được thông qua như đối số cho các thông số method. Bởi vì mảng là loại tham chiếu, các method có thể thay đổi giá trị trong các phần tử.

    Bạn có thể truyền một mảng một chiều, khởi tạo một phương pháp. Ví dụ, các câu sau đây sẽ gửi một mảng cho một method in ấn.

    int[] theArray = { 1, 3, 5, 7, 9 };
    PrintArray(theArray);

    Các mã sau đây cho thấy một thực hiện một phần của method in ấn.

    void PrintArray(int[] arr)
    {
          // Method code.
    }

    Bạn có thể khởi tạo và thông qua một mảng mới trong một bước, như được thể hiện trong ví dụ sau đây.

    PrintArray(new int[] { 1, 3, 5, 7, 9 });

    Trong ví dụ sau đây, một mảng trong dây được khởi tạo và thông qua như một đối số cho một method PrintArray cho các chuỗi. method này sẽ hiển thị các phần tử trong mảng. Tiếp theo, các phương thức ChangeArray và ChangeArrayElement được gọi cho chứng minh là việc gửi một đối số mảng theo giá trị không ngăn cản các thay đổi cho các phần tử mảng.

    class ArrayClass
    {
           static void PrintArray(string[] arr)
           {
                 for (int i = 0; i < arr.Length; i++)
                {
                       System.Console.Write(arr[i] + "{0}", i < arr.Length - 1 ? " " : "");
                }
                System.Console.WriteLine();
           }
           static void ChangeArray(string[] arr)
           {
                  // The following attempt to reverse the array does not persist when
                  // the method returns, because arr is a value parameter.
                  arr = (arr.Reverse()).ToArray();
                  // The following statement displays Sat as the first element in the array.
                  System.Console.WriteLine("arr[0] is {0} in ChangeArray.", arr[0]);
            }

            static void ChangeArrayElements(string[] arr)
            {
                    // The following assignments change the value of individual array
                    // elements.
                    arr[0] = "Sat";
                    arr[1] = "Fri";
                    arr[2] = "Thu";
                    // The following statement again displays Sat as the first element
                    // in the array arr, inside the called method.
                    System.Console.WriteLine("arr[0] is {0} in ChangeArrayElements.", arr[0]);
            }

            static void Main()
            {
                    // Declare and initialize an array.
                    string[] weekDays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
                   // Pass the array as an argument to PrintArray.
                   PrintArray(weekDays);

                   // ChangeArray tries to change the array by assigning something new
                   // to the array in the method.
                   ChangeArray(weekDays);

                  // Print the array again, to verify that it has not been changed.
                  System.Console.WriteLine("Array weekDays after the call to ChangeArray:");
                  PrintArray(weekDays);
                  System.Console.WriteLine();

                  // ChangeArrayElements assigns new values to individual array elements.
                  ChangeArrayElements(weekDays);

                  // The changes to individual elements persist after the method returns.
                  // Print the array, to verify that it has been changed.
                  System.Console.WriteLine("Array weekDays after the call to ChangeArrayElements:");
                  PrintArray(weekDays);
          }
    }
    // Output:
    // Sun Mon Tue Wed Thu Fri Sat
    // arr[0] is Sat in ChangeArray.
    // Array weekDays after the call to ChangeArray:
    // Sun Mon Tue Wed Thu Fri Sat
    //
    // arr[0] is Sat in ChangeArrayElements.
    // Array weekDays after the call to ChangeArrayElements:
    // Sat Fri Thu Wed Thu Fri Sat

    Sử dụng foreach với các mảng

    C# cũng cung cấp các câu lệnh foreach. Câu lệnh này cung cấp một cách đơn giản, trong sạch cho lặp lại thông qua các phần tử của một mảng. Ví dụ, mã sau đây tạo ra một mảng gọi là con số và duyệt qua nó với câu lệnh foreach:

    int[] numbers = { 4, 5, 6, 1, 2, 3, -2, -1, 0 };
    foreach (int i in numbers)
    {
            System.Console.Write("{0} ", i);
    }
    // Output: 4 5 6 1 2 3 -2 -1 0

    Với mảng đa chiều, bạn có thể sử dụng cùng một phương pháp cho lặp lại thông qua các phần tử, ví dụ:

    int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } };
    // Or use the short form:
    // int[,] numbers2D = { { 9, 99 }, { 3, 33 }, { 5, 55 } };

    foreach (int i in numbers2D)
    {
              System.Console.Write("{0} ", i);
    }
    // Output: 9 99 3 33 5 55

    Tuy nhiên, với mảng đa chiều, sử dụng một vòng lặp lồng nhau để giúp bạn kiểm soát nhiều hơn đối với các phần tử mảng.

    Mảng không đều (Jagged Arrays)

    Một mảng không đều là một mảng mà các các phần tử là các mảng. Các yếu tố của một mảng không đều có thể được các kích thước khác nhau và kích cỡ. Một mảng không đều đôi khi được gọi là một "mảng của các mảng." Các ví dụ sau đây cho thấy làm thế nào cho khai báo, khởi tạo, và các mảng truy cập không đều.

    Sau đây là một khai báo của một mảng một chiều là có ba các phần tử, mỗi phần là một mảng một chiều các số nguyên:

    int[][] jaggedArray = new int[3][];

    Trước khi bạn có thể sử dụng jaggedArray, các phần tử của nó phải được khởi tạo. Bạn có thể khởi tạo các các phần tử như thế này:

    jaggedArray[0] = new int[5];
    jaggedArray[1] = new int[4];
    jaggedArray[2] = new int[2];

    Mỗi trong các phần tử là một mảng một chiều các số nguyên. Yếu tố đầu tiên là một mảng trong 5 số nguyên, thứ hai là một mảng của 4 số nguyên, và thứ ba là một mảng của 2 số nguyên.

    Nó cũng có thể sử dụng initializers để điền vào các phần tử của mảng có giá trị, trong trường hợp bạn không cần phải có kích thước mảng. Ví dụ:

    jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 };
    jaggedArray[1] = new int[] { 0, 2, 4, 6 };
    jaggedArray[2] = new int[] { 11, 22 };

    Bạn cũng có thể khởi tạo mảng khi khai báo như thế này:

    int[][] jaggedArray2 = new int[][]
    {
            new int[] {1,3,5,7,9},
            new int[] {0,2,4,6},
            new int[] {11,22}
    };

    Bạn có thể sử dụng hình thức viết tắt sau đây. Chú ý là bạn không thể bỏ qua toán tử mới từ khởi tạo phần tử vì không có khởi tạo mặc định cho các phần tử:

    int[][] jaggedArray3 =
    {
           new int[] {1,3,5,7,9},
           new int[] {0,2,4,6},
           new int[] {11,22}
    };

    Một mảng không đều là một mảng trong mảng, và do đó phần tử của nó là loại tham chiếu và được khởi tạo giá trị null.

    Bạn có thể truy cập phần tử mảng cá nhân như các ví dụ này:

    // Assign 77 to the second element ([1]) of the first array ([0]):
    jaggedArray3[0][1] = 77;

    // Assign 88 to the second element ([1]) of the third array ([2]):
    jaggedArray3[2][1] = 88;

    Nó có thể kết hợp các mảng không đều và đa chiều. Sau đây là một khai báo và khởi tạo một mảng một chiều không đều có chứa ba phần tử mảng hai chiều kích thước khác nhau.

    int[][,] jaggedArray4 = new int[3][,]
    {
           new int[,] { {1,3}, {5,7} },
           new int[,] { {0,2}, {4,6}, {8,10} },
           new int[,] { {11,22}, {99,88}, {0,9} }
    };

    Bạn có thể truy cập vào phần tử cá nhân như trong ví dụ này, hiển thị giá trị của phần tử [1,0] trong mảng đầu tiên (giá trị 5):

    System.Console.Write("{0}", jaggedArray4[0][1, 0]);

    Method này trả về độ dài số mảng chứa trong các mảng không đều. Ví dụ, giả sử bạn đã khai báo mảng trước, dòng này:

    System.Console.WriteLine(jaggedArray4.Length);

    DangTrung.

    Mảng đa chiều (Multidimensional Arrays)

    Mảng có thể có nhiều hơn một chiều. Ví dụ, việc khai báo sau đây tạo ra một mảng hai chiều của bốn hàng và hai cột.

    int[,] array = new int[4, 2];

    Việc kê khai sau đây tạo ra một mảng ba chiều, 4, 2, và 3.

    int[, ,] array1 = new int[4, 2, 3];

    Bạn có thể khởi tạo mảng khi khai báo, như được thể hiện trong ví dụ sau đây.

    // Two-dimensional array.
    int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
    // The same array with dimensions specified.
    int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
    // A similar array with string elements.
    string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },{ "five", "six" } };

    // Three-dimensional array.
    int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },{ { 7, 8, 9 }, { 10, 11, 12 } } };
    // The same array with dimensions specified.
    int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },{ { 7, 8, 9 }, { 10, 11, 12 } } };

    // Accessing array elements.
    System.Console.WriteLine(array2D[0, 0]);
    System.Console.WriteLine(array2D[0, 1]);
    System.Console.WriteLine(array2D[1, 0]);
    System.Console.WriteLine(array2D[1, 1]);
    System.Console.WriteLine(array2D[3, 0]);
    System.Console.WriteLine(array2Db[1, 0]);
    System.Console.WriteLine(array3Da[1, 0, 1]);
    System.Console.WriteLine(array3D[1, 1, 2]);

    Bạn cũng có thể khởi tạo mảng mà không cần xác định thứ hạng.

    int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

    Nếu bạn chọn cho khai báo một biến mảng mà không cần khởi động, bạn phải sử dụng toán tử mới để phân định một mảng đến biến. Việc sử dụng mới này được thể hiện trong ví dụ sau đây.

    int[,] array5;
    array5 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

    Ví dụ sau gán một giá trị cho một phần tử mảng cụ thể.

    array5[2, 1] = 25;

    Tương tự, ví dụ sau đây nhận được giá trị của một phần tử mảng cụ thể và gán nó cho elementValue biến.

    int elementValue = array5[2, 1];

    Ví dụ mã sau khởi tạo các các phần tử mảng cho giá trị mặc định (trừ các mảng không đều).

    int[,] array6 = new int[10, 10];

    DangTrung.

    Cấu hình đơn giản cho Log4j

    Log4j là một framework đơn giản và linh hoạt. Trong hướng dẫn này bạn sẽ học cách cấu hình log4j cho các ứng dụng của bạn. Hãy bắt đầu với việc tải phiên bản mới nhất của log4j (Download). Tôi đang sử dụng phiên bản 1.2.15 log4j. Thêm log4j 1.2.15.jar vào dự án để dự án sử dụng classpath này.

    Tiếp theo, bạn cần tạo một instance của class Logger. Bạn có thể tạo ra một cách sử dụng method Logger.getLogger(HelloWorld.class). Nó cần một đối số tên class đầy đủ.

    Bây giờ chúng ta cần phải cấu hình log4j. Cách đơn giản để làm điều đó là sử dụng Method BasicConfigurator.configure(). Điều này sẽ ghi lại tất cả của tin nhắn trên console.

    Bây giờ mọi thứ đã sẵn sàng, bạn có thể sử dụng message log bất kỳ của các báo cáo in của class Logger. Trong đoạn mã dưới đây tôi sử dụng debug() để hiển thị "HelloWorld!" tin nhắn.


    Những phương pháp khác có được Info(), warn(), error()fatal(). Mỗi phương pháp đều thể hiện một cấp độ logger cụ thể là DEBUG, INFO, WARN, ERROR FATAL.

    Ví dụ dưới đây cho thấy làm thế nào để sử dụng những phương pháp này.


    Đầu ra này có chứa các thời gian trôi qua từ khi bắt đầu chương trình bằng mili giây, tên chủ đề, mức logger, tên lớp và thông điệp log.

    DangTrung.

    Đối tượng Arrays

    Trong C#, mảng là đối tượng thực sự, và không chỉ là vùng địa chỉ bộ nhớ kề nhau như trong C và C++. Array là kiểu cơ sở trừu tượng của tất cả các loại mảng. Bạn có thể sử dụng thuộc tính, và các thành viên lớp kia, mà Array có. Một ví dụ này sẽ sử dụng các tài sản dài để có được chiều dài của một mảng. Các mã sau giao cho chiều dài của dãy số, mà là 5, để một lengthOfNumbers biến được gọi là:

    int[] numbers = { 1, 2, 3, 4, 5 };
    int lengthOfNumbers = numbers.Length;

    Các lớp Array cung cấp nhiều phương pháp hữu ích và thuộc tính để phân loại, tìm kiếm, và các mảng sao chép.

    Ví dụ này sử dụng các property Rank để hiển thị con số kích thước của một mảng.

    class TestArraysClass
    {
         static void Main()
         {
              // Declare and initialize an array:
              int[,] theArray = new int[5, 10];
              System.Console.WriteLine("The array has {0} dimensions.", theArray.Rank);
          }
    }
    // Output: The array has 2 dimensions.

    DangTrung