2011-07-01 36 views
31

Tôi có một lớp học vài mô hình như vậy:Làm thế nào để thêm các thuộc tính để tính một lớp cơ sở của

public class MyModelBase 
{ 
    public string Name { get; set; } 
} 

public class MyModel : MyModelBase 
{ 
    public string SomeOtherProperty { get; set; } 
} 

Làm thế nào có thể MyModel thêm một [Bắt buộc] thuộc tính đến Tên bất động sản?

+0

Bạn có hỏi về chú thích dữ liệu không? Nếu không, thì thuộc tính '[Bắt buộc]' nào bạn đang hỏi. –

Trả lời

26

Thử sử dụng lớp siêu dữ liệu. Đó là một lớp riêng biệt được tham chiếu bằng cách sử dụng các thuộc tính cho phép bạn thêm chú thích dữ liệu vào các lớp mô hình gián tiếp.

ví dụ:

[MetadataType(typeof(MyModelMetadata))] 
public class MyModel : MyModelBase { 
    ... /* the current model code */ 
} 


internal class MyModelMetadata { 
    [Required] 
    public string Name { get; set; } 
} 
+0

Bất kỳ ai quan tâm để bình luận về downvote? Về mặt kỹ thuật, điều này có vẻ đúng với tôi (thậm chí thêm một cái gì đó tương tự như câu trả lời ban đầu của tôi). –

+1

Tôi đoán là điều này chỉ hoạt động đối với các thuộc tính trong vùng tên DataAnnotations và do đó không phải là giải pháp chung. – Marchy

+2

[MSDN] (https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx) nói rằng ** MyModel ** phải là một phần. –

27

Khai báo thuộc tính trong lớp cha mẹ như ảo:

public class MyModelBase 
{ 
    public virtual string Name { get; set; } 
} 

public class MyModel : MyModelBase 
{ 
    [Required] 
    public override string Name { get; set; } 

    public string SomeOtherProperty { get; set; } 
} 

Hoặc bạn có thể sử dụng một MetadataType để xử lý các xác nhận (miễn là bạn đang nói về DataAnnotations ... nếu không bạn' bị mắc kẹt với ví dụ trên):

class MyModelMetadata 
{ 
    [Required] 
    public string Name { get; set; } 

    public string SomeOtherProperty { get; set; } 
} 

[MetadataType(typeof(MyModelMetadata))] 
public class MyModel : MyModelBase 
{ 
    public string SomeOtherProperty { get; set; } 
} 
+1

Đây là cách để đi nếu bạn có hành vi bổ sung mà bạn không muốn mất. +1 – Yuck

+0

Bây giờ bạn phải cẩn thận với các cuộc gọi ảo tiềm năng trong hàm tạo cơ sở. – nicodemus13

+3

Theo [MSDN] (https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx) ** MyModel ** phải là một phần. –

8

Tôi lưu ý rằng không có câu trả lời nào trong số này thực sự gọi chính xác tên cơ sở. Ghi đè nên viết một cái gì đó như sau, để bạn không có một giá trị riêng biệt cho thuộc tính mới.

public class MyModelBase 
{ 
    public virtual string Name { get; set; } 
} 

public class MyModel : MyModelBase 
{ 
    [Required] 
    public override string Name { get { return base.Name; } set { base.Name = value; } 

    public string SomeOtherProperty { get; set; } 
} 
+0

Tôi không thấy, tại sao nó lại cần thiết. Nếu những gì bạn nói là đúng, mã này sẽ không hoạt động, nhưng nó hoạt động: http://csharppad.com/gist/c5db27fb3b90f961a2da. Tôi đoán, trình biên dịch đó tự động xử lý các thuộc tính tự động bị ghi đè. – Spook

+0

@Spook Tôi nghĩ rằng nó sẽ là cần thiết chỉ khi bạn có một số thực hiện tùy chỉnh trong lớp cơ sở (như RaisePropertyChanged trong setter). Nếu bạn chỉ sử dụng các thuộc tính tự động trong lớp con, thì getter/setter trong lớp cơ sở sẽ không được gọi. – Ryan

0

Bạn có thể quá tải thuộc tính cơ sở bằng từ khóa "mới".

public class MyModelBase 
{ 
    public string Name { get; set; } 
} 

public class MyModel : MyModelBase 
{ 
    [Required] 
    public new string Name {get; set;} 
    public string SomeOtherProperty { get; set; } 
} 
+0

Downvote cho cái gì? – ahmet

+1

Điều này "hoạt động" nhưng phá vỡ đa hình. Nếu bạn viết đoạn mã sau "cái gì đó" sẽ là null. MyModel m = new MyModel(); m.Name = "Blah"; MyModelBase mb = m; var something = mb.Name; – raterus

+0

Vì vậy, bạn nói quá tải từ khóa mới là nguy hiểm? Sau đó, nó là gì? – ahmet

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