2009-10-06 18 views
65

Tôi mới đến C# (và OOP). Khi tôi có một số mã như sau:downcast và upcast

class Employee 
{ 
    // some code 
} 


class Manager : Employee 
{ 
    //some code 
} 

Câu hỏi 1: Nếu tôi có mã khác mà thực hiện điều này:

Manager mgr = new Manager(); 
    Employee emp = (Employee)mgr; 

Đây Employee là một Manager, nhưng khi tôi đúc nó như thế đến một số Employee có nghĩa là tôi đang upcasting nó?

Câu hỏi 2:

Khi tôi có một vài Employee đối tượng lớp và một số nhưng không phải tất cả trong số đó là Manager 's, làm thế nào tôi có thể downCast họ nếu có thể?

+2

Hy vọng bạn không phiền, tôi đã sửa "lỗi cú pháp" trong câu hỏi của bạn;) – RCIX

+1

xin lỗi tôi hơi nghèo bằng tiếng Anh – user184805

+1

Không sao đâu! – RCIX

Trả lời

66
  1. Điều đó là chính xác. Khi bạn làm điều đó bạn đang đúc nó vào một đối tượng employee, do đó có nghĩa là bạn không thể truy cập vào bất kỳ trình quản lý cụ thể nào.

  2. Downcasting là nơi bạn có một lớp cơ sở và sau đó thử và biến nó thành một lớp cụ thể hơn. Điều này có thể được thực hiện với việc sử dụng là và một diễn viên rõ ràng như thế này:

    if (employee is Manager) 
    { 
        Manager m = (Manager)employee; 
        //do something with it 
    } 
    

hoặc với các nhà điều hành as như thế này:

Manager m = (employee as Manager); 
if (m != null) 
{ 
    //do something with it 
} 

Nếu bất cứ điều gì không rõ ràng tôi sẽ được hạnh phúc để sửa chữa nó!

+0

Tôi cần ví dụ để biết Downcasting là gì? – user184805

+3

Tránh xác định lại các thuật ngữ được thiết lập tốt: “quyền anh”, trong ngữ cảnh của OOP và C#, có nghĩa là một cái gì đó khá khác (= gói một đối tượng kiểu giá trị vào tham chiếu). Ngoài ra, ví dụ của bạn có thể (và nên) sử dụng toán tử 'as' thay vì' is', theo sau là một phép diễn. –

+1

Tôi đã sửa chữa ở điểm đầu tiên và tôi đã thay đổi phần thứ hai của câu trả lời để hiển thị cả hai cách thực hiện. – RCIX

40

Upcasting (sử dụng (Employee)someInstance) thường dễ dàng như trình biên dịch có thể cho bạn biết tại thời gian biên dịch nếu loại có nguồn gốc từ một loại khác.

Downcasting tuy nhiên phải được thực hiện tại thời gian chạy nói chung vì trình biên dịch có thể không phải lúc nào cũng biết liệu cá thể được đề cập có thuộc loại được cung cấp hay không. C# cung cấp hai toán tử cho điều này - cho bạn biết công việc downcast và trả về true/false. Và cố gắng thực hiện việc truyền và trả về đúng loại nếu có thể, hoặc null nếu không.

Để kiểm tra nếu một nhân viên là một người quản lý:

Employee m = new Manager(); 
Employee e = new Employee(); 

if(m is Manager) Console.WriteLine("m is a manager"); 
if(e is Manager) Console.WriteLine("e is a manager"); 

Bạn cũng có thể sử dụng này

Employee someEmployee = e as Manager; 
    if(someEmployee != null) Console.WriteLine("someEmployee (e) is a manager"); 

Employee someEmployee = m as Manager; 
    if(someEmployee != null) Console.WriteLine("someEmployee (m) is a manager"); 
5

Trong trường hợp bạn cần phải kiểm tra từng đối tượng người lao động cho dù đó là một đối tượng quản lý, sử dụng phương pháp OfType:

List<Employee> employees = new List<Employee>(); 

//Code to add some Employee or Manager objects.. 

var onlyManagers = employees.OfType<Manager>(); 

foreach (Manager m in onlyManagers) { 
    // Do Manager specific thing.. 
} 
3
  • Upcasting là một thao tác tạo tham chiếu lớp cơ sở từ tham chiếu lớp con. (subclass -> superclass) (tức làNgười quản lý -> Nhân viên)
  • Downcasting là một hoạt động tạo tham chiếu lớp con từ tham chiếu lớp cơ sở. (Lớp cha -> lớp con) (ví dụ: nhân viên -> Manager)

Trong trường hợp của bạn

Employee emp = (Employee)mgr; //mgr is Manager 

bạn đang làm một upcasting.

Một bị ném lên trời luôn thành công không giống như một yếu hèn mà đòi hỏi một diễn viên rõ ràng bởi vì nó có khả năng có thể thất bại khi chạy. (InvalidCastException).

C# cung cấp hai nhà khai thác để tránh ngoại lệ này được ném:

Bắt đầu từ:

Employee e = new Employee(); 

Đầu tiên:

Manager m = e as Manager; // if downcast fails m is null; no exception thrown 

Thứ hai:

if (e is Manager){...} // the predicate is false if the downcast is not possible 

Cảnh báo: Khi bạn làm một sự liệng lên bạn chỉ có thể truy cập vào các phương pháp của lớp cha, tài sản vv ...

-1

Upcasting và downcasting:

Upcasting: Đúc từ nguồn gốc-Class để Base Class downcasting: Đúc từ Base class class nguồn gốc

Hãy hiểu giống như một ví dụ:

Hãy xem xét hai lớp Shape như lớp cha của tôi và Circle như một lớp Derived, được xác định như sau:

class Shape 
{ 
    public int Width { get; set; } 
    public int Height { get; set; } 
} 

class Circle : Shape 
{ 
    public int Radius { get; set; } 
    public bool FillColor { get; set; } 
} 

Upcasting:

Shape s = new Shape();

Vòng tròn c = s; Cả hai c và s đều tham chiếu đến cùng một vị trí bộ nhớ, nhưng cả hai đều có quan điểm khác nhau, sử dụng tham chiếu "c", bạn có thể truy cập tất cả các thuộc tính của lớp cơ sở và lớp dẫn xuất, nhưng sử dụng tham chiếu "s" bạn có thể truy cập các thuộc tính của lớp cha duy nhất.

Một ví dụ thực tế của upcasting là lớp Suối đó là baseclass của tất cả các loại đầu đọc dòng net framework:

đọc StreamReader = new StreamReader (mới FileStreamReader());

tại đây, FileStreamReader() được upcasted thành streadm reder.

downcasting:

Shape s = new Circle(); ở đây như được giải thích ở trên, quan điểm của s là cha mẹ duy nhất, để làm cho nó cho cả cha và con chúng ta cần downcast nó

var c = (Circle) s;

Ví dụ thực tế về Downcasting là lớp nút của WPF.

Các vấn đề liên quan