2013-06-11 26 views
12

Tôi có mã kế thừa bằng cách sử dụng BaseClass và mã được mong đợi là customerid là loại int. Sau đó, tôi có một yêu cầu để tạo ra một lớp mới, DerivedClass, hoạt động rất giống BaseClass nhưng bây giờ customerid cần phải là một chuỗi. Không thể sửa đổi mã cũ để kiểm tra không cần thiết.Có cách nào để sử dụng thuộc tính có cùng tên nhưng có loại khác trong lớp dẫn xuất không?

Làm cách nào để có hiệu ứng tôi muốn sử dụng thừa kế (hoặc bất kỳ cách nào khác)?

Mã kiểm tra Linqpad dưới đây minh họa những gì tôi cần làm. Rõ ràng nó sẽ không biên dịch bởi vì customerid trong DerivedClass cần phải là int. Tôi cần một chuỗi tài sản được gọi là customerid là tốt. Nó cần phải là tên đó bởi vì các mã khác sẽ sử dụng lớp này thay vì BaseClass và hy vọng cùng một thuộc tính được đặt tên là kiểu chuỗi.

public class BaseClass 
{ 
    public virtual int customerid {get; set;} 

    public void printname() 
    { 
     customerid = 1; 
     customerid.Dump(); 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public override string customerid {get; set;} 

    public void PrintCustomerID() 
    { 
     customerid = "jshwedeX"; 
     customerid.Dump(); 
    } 
} 



void Main() 
{ 
    DerivedClass dc = new DerivedClass(); 
    dc.printname(); 
} 
+3

Bạn có thể sử dụng [triển khai giao diện rõ ràng] (http://msdn.microsoft.com/en-us/library/vstudio/ms173157.aspx) không? – millimoose

+0

Đối với lập trình VB, sử dụng từ khóa 'Bóng tối' khi tạo định nghĩa mới cho thuộc tính, trường, v.v. Điều này có thể ảnh hưởng đến lập trình động của bạn khi truyền sang loại cha nếu giá trị trả về không khớp. – ps2goat

Trả lời

21

Bạn có thể sử dụng modifier new như thế này:

public class BaseClass 
{ 
    public virtual int customerid {get; set;} 

    public void printname() 
    { 
     customerid = 1; 
     customerid.Dump(); 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public new string customerid {get; set;} 

    public void PrintCustomerID() 
    { 
     customerid = "jshwedeX"; 
     customerid.Dump(); 
    } 
} 

này sẽ cung cấp cho bạn những kết quả mong muốn, nhưng nó cũng sẽ che giấu tài sản trên lớp cơ sở. Nếu bạn tham chiếu một thể hiện của DerivedClass dưới dạng biến số BaseClass, bạn sẽ chỉ có thể tham chiếu thuộc tính trên lớp cơ sở; không phải là lớp dẫn xuất.

Nói cách khác:

BaseClass instance = new DerivedClass(); 
string customerId = instance.customerid; // <- this won't compile 

Một thay thế sẽ được sử dụng triển khai giao diện rõ ràng:

public interface IBase 
{ 
    int customerid { get; set; } 
} 

public interface IDerived 
{ 
    string customerid { get; set; } 
} 

public class Derived : IBase, IDerived 
{ 
    int IBase.customerid { get; set; } 
    string IDerived.customerid { get; set; } 
} 

Khi bạn thể hiện của Derived được lưu trữ trong một biến kiểu IBase, customerid sẽ giải quyết để phiên bản int và khi được lưu trữ theo loại IDerived, phiên bản này sẽ giải quyết thành phiên bản string:

var derived = new Derived(); 
IBase ibase = derived; 
IDerived iderived = derived; 
int id1 = ibase.customerid; // <- compiles just fine 
string id2 = iderived.customerid; // <- compiles just fine 

Bạn cũng có thể sử dụng đúc:

var instance = new Derived(); 
int id1 = ((IBase)instance).customerid; 
string id2 = ((IDerived)instance).customerid; 

Hãy ghi nhớ rằng việc triển khai giao diện rõ ràng gây ra các thành viên thực hiện để không được hiển thị trừ khi biến là các loại giao diện:

var instance = new Derived(); 
var customerid = instance.customerid; // <- this won't compile 
+1

+1 thích giao diện rõ ràng hơn che giấu ý nghĩa của cơ sở –

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