2011-11-04 44 views
8

bằng C# Tôi có một lớp chứa các thông tin meta khác nút gốc của biểu đồ được chỉ dẫn. Hãy gọi đây là Vùng chứa. Vùng chứa này có thể xuất hiện ở hai chế độ khác nhau, Chế độ biên tập và Chế độ cấu hình. Tùy thuộc vào chế độ, nút gốc của một loại khác là NodeEdit hoặc NodeConfig, cả hai đều được kế thừa từ cùng một lớp con.Thay đổi Loại thuộc tính kế thừa (thành kiểu được kế thừa)

public abstract class NodeBase 
{ 
    string Name { get; set; } 
    ... 
} 

public class NodeEdit : NodeBase ... 
public class NodeConfig : NodeBase ... 

Đối với container, tôi cũng tạo ra một lớp cơ sở và kế thừa từ nó:

public abstract class ContainerBase 
{ 
    NodeBase Root { get; set; } 
    ... 
} 

Khi tạo các lớp học cho tổng biên tập và Configuratorcontainer bởi kế thừa từ ContainerBase, tôi muốn trở thành loại Root - thuộc tính cụ thể (kế thừa từ NodeBase) loại như:

public class ContainerEditor : ContainerBase 
{ 
    NodeEditor Root { get; set; } 
    ... 
} 

Nhưng tôi không thể thay đổi loại thuộc tính được định nghĩa trong ContainerBase. Có cách nào để giải quyết vấn đề này không? Tôi có thể sử dụng BaseNode-type, và thêm một phần tử của NodeEditor như

ContainerEditorInstance.Root = new NodeEditor(); 

vì loại NodeEditor được thừa hưởng từ loại BaseEditor, nhưng trong lớp container-Editor, tôi muốn dứt khoát chỉ cho phép các loại hình Thuộc tính gốc là NodeEditor. Tôi có thể kiểm tra điều này trong setter và từ chối tất cả các nút, nhưng các loại NodeEditor, nhưng tôi muốn có tài sản được loại cụ thể, vì vậy tôi có thể phát hiện sai nhiệm vụ tại thời gian biên dịch.

Cảm ơn trước,
Frank

Trả lời

4

Bạn có thể redeclare nó:

public class ContainerEditor : ContainerBase 
{ 
    public NodeEditor Root { 
    get { return (NodeEditor)base.Root; } 
    set { base.Root = value; } 
    } 
    ... 
} 
+0

Xin chào Marc, cảm ơn bạn đã trả lời! Tôi đã thử nó với lời khai báo, nhưng có lẽ tôi đã làm điều gì sai. Tôi đã thử nghiệm cách tiếp cận của bạn và nó hoạt động tốt! Nói chung, có những tình huống mà redeclaring nên được ưa thích để Generics hoặc vica versa hoặc là họ bằng nhau? – Aaginor

+0

Toàn bộ công cụ chung này gây ra các vấn đề nghiêm trọng khi lớp cơ sở chung được sử dụng tức là một dạng lặp lại trừu tượng.Vì vậy, tôi sẽ cho redeclaring một shot, cho nó có vẻ là ít xâm nhập. So với 'mới' và 'ghi đè', làm thế nào là redeclaring làm việc trong nội bộ? Có bài viết hay về nó, bạn có thể giới thiệu? Cảm ơn một lần nữa! – Aaginor

9

Sử dụng Generics:

public abstract class ContainerBase<T> where T:NodeBase 
{ 
    T Root { get; set; } 
    ... 
} 

public class ContainerEditor : ContainerBase<NodeEditor> 
{  
    ... 
} 
+0

Hi Blau, không bao giờ giải quyết Generics bên cạnh HashSet thường và sử dụng tương tự. Hãy nghĩ rằng đây có lẽ sẽ là thời điểm tốt để làm việc với họ! – Aaginor

1

Bạn có thể làm cho các cơ sở chứa chung:

public abstract class ContainerBase<TRoot> where TRoot : NodeBase 
{ 
    TRoot Root { get; set; } 
    ... 
} 

Trong lớp có nguồn gốc bạn chỉ định các loại:

public class ContainerEditor : ContainerBase<NodeEditor> 
{ 
    ... 
} 
+0

Ý tưởng hay, tôi sẽ chụp. – Aaginor

0

Tôi cho rằng một giải pháp tốt ở đây sẽ là Generics. Vì vậy, bạn muốn viết một cái gì đó như thế này:

public class ContainerEditor<T>:ContainerBase 
{ 
    T Root {get;set;} 
} 
+0

Tôi sẽ cần khai báo Root trong ContainerBase để có thể truy cập nó trong các chức năng mà không cần biết Wheter là Editor hoặc Configurator của nó. Dù sao các generics giống như một ý tưởng hay, như Guffa và Blau đã cho thấy. – Aaginor

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