2010-10-29 39 views
5

Nếu:đúc vĩnh viễn vào một lớp cha

class Car : Automobile 
{} 

tôi có thể làm:

Car toyota = new Car(); 
Automobile tauto = (Automobile)toyota; 

nhưng nếu tôi làm tauto.GetType().Name nó vẫn sẽ xe.

Có thể thực hiện dàn diễn viên, để loại được thay đổi vĩnh viễn thành ô tô (không phải sao chép đối tượng)?

Vấn đề tôi đang cố khắc phục là không có nhiều thừa kế trong C# và tôi cần hợp nhất các đối tượng (có cùng chữ ký) từ 2 dịch vụ, trong một phương thức và trả về một loại.

+1

Chỉ tò mò: tại sao bạn muốn thực hiện việc này? –

+1

Xin lỗi vì đã hỏi nhưng tại sao bạn lại muốn làm điều đó? Đối tượng ** là ** Ô tô, không phải ô tô. Nếu bạn muốn một ô tô sau đó nhanh chóng một. – Lazarus

+0

câu chuyện dài, nhưng nó liên quan đến Entity Framework, POCOs, và không có khả năng sử dụng cùng một lớp POCO được trả về bởi 2 bộ thực thể khác nhau. Vì vậy, tôi có để có được xung quanh đó bằng thừa kế .. Nhưng bên ngoài sẽ, tôi muốn các đối tượng từ cả hai quan điểm là như nhau .. vì vậy chỉ cần trả lại các lớp siêu. đơn giản là vấn đề bởi vì những thứ như WCF serializer và .net 3,5 generics vẫn đối xử với các đối tượng cast như subclass –

Trả lời

11

Không. Không có cách nào để thực hiện việc này mà không cần tạo đối tượng ô tô mới ô tô mới.

Tuy nhiên, cũng không có lý do để thực hiện việc này. Các Liskov substitution principle nói rằng bất kỳ Car nên, luôn luôn, có thể điều trị chính xác như một Automobile, và người dùng sẽ không có thay đổi trong hành vi dự kiến.

Miễn là bạn thiết kế phân cấp lớp một cách chính xác, việc sử dụng Car làm Automobile phải luôn được chấp nhận hoàn toàn.


Lưu ý: Đây là một phần lý do tại sao sử dụng Type.GetType() không phải là cách ưa thích để kiểm tra loại. An toàn hơn và tốt hơn, để sử dụng các từ khóa isas trong C#. Chúng sẽ trả về true nếu bạn kiểm tra xem tauto is Car.

+1

tiếc là quan tâm serializer wcf, và 3,5 generics cũng quan tâm .. vì vậy tôi không thể chỉ đơn giản là thay đổi mã đó .. tôi biết tôi có thể cung cấp serialization của riêng tôi nhưng nó mang lại cho tôi rất nhiều đau đầu khắp nơi .. –

+0

3,5 generics không quan tâm - cấp, có một số vấn đề tiềm năng với WCF serialization, mặc dù đó là hiếm, và bạn nên làm cho anyways lớp serializable của bạn. Nếu bạn thực sự cần làm cho nó trở thành một lớp con, bạn sẽ cần phải xây dựng một đối tượng mới. Chỉ cần tạo một hàm tạo mới trên ô tô giống như thế này: 'Ô tô công cộng (ô tô khác)', và sau đó bạn có thể tạo ra điều đó khi đi đến một thói quen thực sự quan tâm ... –

0

Theo MSDN, bạn chỉ cần truyền tài liệu tham khảo cho đối tượng chứ không phải đối tượng bên dưới.

0

Câu hỏi của bạn và những gì bạn đang cố gắng làm có vẻ như hai điều khác nhau. Không, bạn không thể thay đổi kiểu cơ bản của một đối tượng. Nhưng những gì bạn dường như muốn làm là tạo ra một loại ô tô với tập hợp các thuộc tính và không thực sự sử dụng phân lớp. Những gì bạn có thể làm là sử dụng một nhà máy ô tô để thay thế.

public static class AutomobileFactory() 
{ 
    public static Automobile CreateAutomobile(AutomobileType type) 
    { 
    ... 
    } 
} 

Trường hợp AutomobileType là enum. Để biết thêm thông tin, Google C# Mẫu nhà máy.

0

Tôi không chắc chắn chính xác bạn đang cố gắng làm gì, nhưng có lẽ bạn có thể xem xét một cách tiếp cận khác? Thay vì cố gắng hợp nhất các chức năng của hai lớp khác nhau bằng cách sử dụng thừa kế, có lẽ bạn có thể sử dụng bố cục?

http://tiedyedfreaks.org/eric/CompositionVsInheritance.html

public class Service 
{ 
    public virtual void DoSomething() 
    { 

    } 
} 

public class ServiceA : Service 
{ 
    public override void DoSomething() 
    { 

    } 
} 

public class ServiceB : Service 
{ 
    public override void DoSomething() 
    { 

    } 
} 

public class ServiceA_B : Service 
{ 
    ServiceA serviceA = new ServiceA(); 
    ServiceB serviceB = new ServiceB(); 

    public override void DoSomething() 
    { 
     serviceA.DoSomething(); 
     serviceB.DoSomething(); 
    } 
} 
0

Trong một số trường hợp, thuốc generic có thể giúp đỡ. Nếu một phương thức bao gồm một tham số chung, kiểu generic sẽ được đánh giá là kiểu khai báo của tham chiếu được truyền vào, thay vì kiểu của đối tượng được truyền vào. Ví dụ:

 
void Foo(T bar) 

Nếu foo() được gọi với (Control) someButton, loại 'bar' sẽ là Nút nhưng loại T sẽ là Kiểm soát.

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