Lập Trình C# - Cấu Trúc Chương Trình

Nội dung:





Namespaces
Mỗi class được gói lại trong một namespace. Thật ra, namespaces là một khái niệm trong C++, nhưng trong C# chúng ta dùng namespaces thường xuyên hơn. Các bạn có thể truy xuất một class trong một namespaces bằng cách dùng dấu chấm (.). MyNameSpace là namespace của chương trình Hello world ở trên.
Bây giờ chúng ta hãy viết lại chương trình HelloWorldbằng cách truy xuất lớp HelloWorld từ một lớp khác trong một namespaces khác:
#Code:
using System;
namespace AnotherNameSpace
{
class AnotherClass
{
    public void Func()
   {
          Console.WriteLine (“Hello World”);
   }
}
}
Bây giờ từ lớp HelloWorld, các bạn có thể truy xuất nó:
#Code:
using System;
using AnotherNameSpace;
namespace MyNameSpace
{
class HelloWorld
{
    static void Main(string[] args)
   {
      AnotherClass obj = new AnotherClass();
      obj.Func();
   }
}
}
Using
Chỉ thị #include trong C++ được thay thế bởi từ khóa using, theo sau đó là tên của một namespace, chẳng hạn như “using System”. System là một namespace nền trong đó chứa tất cả những namespace khácvà tất cả các lớp được định nghĩa trong những namespace đó. Lớp nền cho mọi đối tượng là Object trong namespace System.
Biến
Các biến trong C# hầu hết đều giống trong C++, ngoại trừ những khác biệt sau:
Biến trong C# luôn cần phải khởi tạo trước khi bạn truy xuất nó, nếu không bạn sẽ bị báo lỗi trong khi biên dịch. Do đó, phải nhớ rằng không thể truy xuất một biến chưa được khởi tạo.
Bạn không thể truy xuất một con trỏ không trỏ vào đâu cả trong C#.
Một biểu thức không thể gọi một phần tử của mảng (array) mà chỉ số của nó vượt ra khỏi kích thước của mảng.
Không có khái niệm biến toàn cục hay hàm toàn cục trong C# và những khái niệm về toàn cục được biểu diễn thông qua những hàm và biến static.
Kiểu dữ liệu
Tất cả những kiểu dữ liệu của C# được định nghĩa trong lớp Object. Có hai loại kiểu dữ liệu:
Kiểu dữ liệu cơ bản (dựng sẵn).
Kiểu dữ liệu do người dùng định nghĩa.
Dưới đây là bảng liệt kê các kiểu dữ liệu định sẵn trong trong C#:
Kiểu               Kích thước          Mô tả
Byte                      1                 unsigned byte
Sbyte                    1                   signed byte
Short                    2                  signed short
Ushort                  2                 unsigned short
Int                         4                 signed integer
Uint                      4                unsigned integer
Long                     8                     signed long
Ulong                    8                   unsigned long
Float                     4                   floating point
Double                  8                 double precision
Decimal                8                   fixed precision
String              unicode                  string
Char                unicode                   char
Bool                true, false               boolean
Kiểu giá trị
Kiểu giá trị là những dữ liệu được cấp phát bộ nhớ trong stack. Các loại dữ liệu này bao gồm: Tất cả những kiểu dữ liệu dựng sẵn ngoại trừ kiểu string.
Struct
Kiểu liệt kê
Kiểu tham khảo
Kiểu tham khảo được cấp phát bộ nhớ trên heap và sẽ trở thành rác khi chúng không được sử dụng nữa. Để khai báo kiểu dữ liệu này, ta dùng từ khóa new, và không như C++, không có từ khóa delete. Trong C#, chúng tự động được gom lại bởi “ bộ phận thu thập rác” (garbage collector).
Kiểu tham khảo bao gồm:
Class
Interface
Kiểu tập hợp như mảng:
String
Kiểu liệt kê (Enumeration)
Kiểu liệt kê trong C# hoàn toàn giống như C++, chúng được định nghĩa thông qua từ khóa enum.
#Code:
enum Weekdays
{
    Saturday, Sunday, Monday
    Tuesday, Wednesday, Thursday, Friday
}
Class và Struct
Class và Struct cũng tương tự như C++, ngoại trừ sự khác nhau về sự cấp phát bộ nhớ. Những đối tượng của class được cấp phát bộ nhớ trong heap và được tạo ra bằng cách dùng new, còn struct được cấp phát bộ nhớ trong stack.
Struct trong C# là kiểu dữ liệu rất nhẹ và nhanh. Do đó đối với những kiểu dữ liệu nặng bạn nên khai báo class.
#Code:
struct Date
{
   int day;
   int month;
   int year;
}
class Date
{
   int day;
   int month;
   int year;
   string weekday;
   string monthName;
   public int GetDay()
   {
       return day;
   }
  public int GetMonth()
  {
       return month;
  }
 public int GetYear()
 {
       return year;
 }
 public void SetDay(int Day)
 {
       day = Day ;
 }
 public void SetMonth(int Month)
 {
       month = Month;
 }
public void SetYear(int Year)
{
       year = Year;
}
public bool IsLeapYear()
{
       return (year/4 == 0);
}
public void SetDate (int day, int month, int year)
{
}
...
}
Các thuộc tính
Nếu bạn đã quen thuộc với hướng đối tượng trong C++, bạn ắt hẳn phải có chút khái niệm gì đó về thuộc tính (properties). Các thuộc tính trong ví dụ class Date ở trên là day, month và year. Nếu trong C++, bạn phải dùng phương thức Get và Set thì C# cung cấp những cách thuận tiện hơn, đơn giản hơn và trực tiếp hơn để truy xuất những thuộc tính.
#Code:
using System;
class Date
{
public int Day{
get {
return day;
}
set {
day = value;
}
}
int day;
public int Month{
get {
return month;
}
set {
month = value;
}
}
int month;
public int Year{
get {
return year;
}
set {
year = value;
}
}
int year;
public bool IsLeapYear(int year)
{
return year%4== 0 ? true:false;
}
public void SetDate (int day, int month, int year)
{
this.day = day;
this.month = month;
this.year = year;
}
}
Sau đây là cách bạn lấy và thiết lập thuộc tính:
class User
{
   public static void Main()
   {
       Date date = new Date();
       date.Day = 27;
       date.Month = 6;
       date.Year = 2003;
              Console.WriteLine(“Date: {0}/{1}/{2}”,date.Day, date.Month, date.Year);
    }
}
Bổ từ (Modifier)
Trong C++, chúng ta đã gặp các bổ từ thông dụng như public, private và protected. Sau đây chúng ta sẽ nói về một số bổ từ mới trong C#.
Readonly
readonly chỉ được dùng cho những dữ liệu thành viên (member) của class. Dữ liệu readonly chỉ có thể đọc được khi chúng đã được khởi tạo trực tiếp hay gán giá trị cho chúng trong constructor. Sự khác nhau giữa dữ liệu readonly và const (hằng) là khi khai báo hằng, ta phải khởi tạo giá trị cho nó một cách trực tiếp.
#Code:
class MyClass
{
    //trực tiếp
    const int constInt = 100;
    //không trực tiếp
    readonly int myInt = 5;
    readonly int myInt2;
    public MyClass()
    {
        // không trực tiếp
        myInt2 = 8;
     }
    public Func()
    {
          myInt = 7; //không hợp lệ
          Console.WriteLine(myInt2.ToString());
     }
}
Sealed
Sử dụng từ khóa sealed khi khai báo một class sẽ không cho phép bạn lấy bất kỳ class nào từ nó. Do đó bạn nên sử dung từ khóa sealed cho những lớp mà bạn không muốn những lớp con thừa kế chúng.
#Code:
sealed class CanNotbeTheParent
{
     int a = 5;
}
Unsafe
Bạn có thể định nghĩa một ngữ cảnh không an toàn trong C# bằng cách dùng từ khóa unsafe.

Trong ngữ cảnh không an toàn, bạn có thể viết một đoạn mã không an toàn.
#Code:
public unsafe MyFunction( int * pInt, double* pDouble)
{
      int* pAnotherInt = new int;
     *pAnotherInt = 10;
      pInt = pAnotherInt;
      ...
     *pDouble = 8.9;
}
Interface
Nếu bạn đã có khái niệm về COM, bạn sẽ dễ dàng hiểu được nội dung của phần này. Một interface là một lớp trừu tượng cơ bản, trong đó chỉ chứa những ký hiệu của hàm, sự hiện thực những hàm này được cung cấp bởi những lớp con.
Trong C#, bạn có thể định nghĩa những class như những interface thông qua từ khóa interface. .NET có nền tảng từ nhiều interface. Trong C# bạn không thể dùng nhiều lớp thừa kế, điều mà trong C++ cho phép, nhưng thật ra bản chất của sự đa thừa kế được thực hiện thông qua interface. Những lớp con của bạn cũng có thể hiện thực đa interface.
#Code:
using System;
interface myDrawing
{
      int originx
      {
          get;
          set;
      }
     int originy
     {
         get;
         set;
     }
    void Draw(object shape);
}
class Shape: myDrawing
{
     int OriX;
     int OriY;
     public int originx
     {
        get{
              return OriX;
        }
       set{
              OriX = value;
       }
      }
     public int originy
     {
        get{
              return OriY;
        }
        set{
               OriY = value;
        }
     }
     public void Draw(object shape)
     {
         ...
     }
    public void MoveShape(int newX, int newY)
    {
       .....
    }
}
Mảng
Mảng trong C# có nhiều tính năng vượt trội hơn so với C++. Mảng được cấp phát bộ nhớ trong heap và do đó nó được truyền bằng tham khảo. Bạn không thể truy xuất một phần tử vượt ngoài giới hạn trong một mảng (có chỉ số lớn hơn số phần tử trong mảng). Do đó C# đã khắc phục lỗi này. Ngoài ra C# còn cung cấp một số hàm trợ giúp để xử lý các phần tử
trong mảng. Ta có thể thấy rõ sự khác nhau giữa cú pháp của mảng trong C++ và C# là:
Dấu ngoặc vuông được đặt sau tên kiểu chứ không phải sau tên biến.
Bạn có thể tạo vùng nhớ cho phần tử trong mảng bằng cách dùng từ khóa new.
Ngoài ra C# còn hỗ trợ việc hiện thực mảng một chiều (single dimensional), đa chiều (multi dimensional) và jagged array (mảng của mảng).
#Code:
// mảng một chiều đơn giản
int[] array = new int[10];
for (int i = 0;i < array.Length; i++)
array[i] = i;
// mảng hai chiều
int[,] array2 = new int[5,10];
array2[1,2] = 5;
// mảng 3 chiều
int[,,] array3 = new int[5,10,5];
array3[0,2,4] = 9;
// mảng của mảng
int[][] arrayOfarray = = new int[2];
arrayOfarray[0] = new int[4];
arrayOfarray[0] = new int[] {1,2,15};
Indexer
Indexer được dùng để viết một phương thức truy xuất trực tiếp một phần tử từ một tập hợp bằng cách dùng dấu [ ], như trong mảng. Việc bạn cần làm chỉ là chỉ rõ chỉ số để truy xuất một phần tử. Cú pháp của một indexer cũng giống như của thuộc tính một class, ngoại trừ chúng cần một thông số nhập, đó chính là chỉ số của phần tử cần truy xuất.
Bây giờ chúng ta tiếp tục tham khảo một ví dụ cho vấn đề này. Trong ví dụ sau bạn sẽ bắt gặp lớp CollectionBase, đó là một lớp thư viện dùng để tạo ra những tập hợp. Danh sách (list) là một protected member của lớp CollectionBase, trong đó lưu trữ tập hợp các danh sách.
#Code:
class Shapes: CollectionBase
{
      public void add(Shape shp)
      {
          List.Add(shp);
      }
      //indexer
      public Shape this[int index]
      {
          get {
                 return (Shape) List[index];
          }
         set {
                List[index] = value ;
         }
      }
}
Boxing/Unboxing
Boxing là một khái niệm mới trong C#. Như đã đề cập ở trên, mọi kiểu dữ liệu, dựng sẵn hay do người dùng định nghĩa, đều được lấy từ một lớp cơ bản là Object trong namespace System.
Do đó việc đóng gói những kiểu căn bản hay nguyên thủy vào trong class Object được gọi là boxing, và thao tác ngược lại được gọi là unboxing.
#Code:
class Test
{
    static void Main()
    {
       int myInt = 12;
       // boxing
       object obj = myInt ;
       // unboxing
      int myInt2 = (int) obj;
    }
}
Delegate
Delegate cho phép chúng ta lưu sự tham khảo hàm vào một biến. Trong C++, việc này giống như dùng và lưu con trỏ hàm và chúng ta hay dùng typedef.
#Code:
delegate int Operation(int val1, int val2);
public int Add(int val1, int val2)
{
     return val1 + val2;
}
public int Subtract (int val1, int val2)
{
    return val1- val2;
}
public void Perform()
{
    Operation Oper;
    Console.WriteLine(“Enter + or - “);
    string optor = Console.ReadLine();
    Console.WriteLine(“Enter 2 operands”);
    string opnd1 = Console.ReadLine();
    string opnd2 = Console.ReadLine();
    int val1 = Convert.ToInt32 (opnd1);
    int val2 = Convert.ToInt32 (opnd2);
    if (optor == “+”)
         Oper = new Operation(Add);
    else
         Oper = new Operation(Subtract);
         Console.WriteLine(“ Result ={0}”, Oper(val1, val2));
}
Tính thừa kế và tính đa hình
Trong C# chỉ cho phép sự thừa kế đơn. Nếu bạn muốn thực hiện đa thừa kế, bạn có thể dùng interface.
#Code:
class Parent{
}
class Child : Parent
Hàm ảo
Từ khái niệm hàm ảo đến hiện thực khái niệm đa hình trong C# là như nhau, ngoại trừ việc bạn dùng từ khóa override đối với việc hiện thực hàm ảo trong lớp con. Lớp cha vẫn sử dụng từ khóa virtual. Lớp nào overridephương thức ảo cũng sử dụng từ khóa override.
#Code:
class Shape
{
     public virtual void Draw()
     {
         Console.WriteLine(“Shape.Draw”);
     }
}
class Rectangle : Shape
{
      public override void Draw()
      {
         Console.WriteLine(“Rectangle.Draw”);
      }
}
class Square : Rectangle
{
       public override void Draw()
       {
          Console.WriteLine(“Square.Draw”);
       }
}
class MainClass
{
       static void Main(string[] args)
       {
            Shape[] shp = new Shape[3];
            Rectangle rect = new Rectangle();
            shp[0] = new Shape();
            shp[1] = rect;
            shp[2] = new Square();
            shp[0].Draw();
            shp[1].Draw();
            shp[2].Draw();
        }
}

1 Comment:

Are you looking to make cash from your visitors by using popunder advertisments?
If so, did you know about PopCash?

Đăng nhận xét

Thank you for your comments!