2010-09-23 38 views
7

Có thể tôi nên thậm chí không được cố này ở nơi đầu tiên, nhưng đây là những gì tôi có cho đến nay:Thuộc tính tự động C# - có thể có getter tùy chỉnh với setter mặc định không?

public List<int> AuthorIDs 
{ 
    get 
    { 
     var l = new List<int>(); 
     using (var context = new GarbageEntities()) 
     { 
      foreach (var author in context.Authors.Where(a => a.Books.Any(b => b.BookID == this.BookID)).ToList()) 
      { 
       l.Add(author.AuthorID); 
      } 
     } 
     return l; 
    } 
    set; //compiler error 
} 

Làm thế nào tôi sẽ rời khỏi setter trên mà không bất kỳ loại logic tùy chỉnh? Trong những ngày xa xưa, tôi nghĩ bạn sẽ chỉ sử dụng:

set { authorIDs = value; } 

hiện không hoạt động.

Đây có phải là toàn bộ ý tưởng thật khủng khiếp khi bắt đầu không?

Edit:

Để trả lời câu hỏi của một số người: Tôi đang cố gắng để kết hợp MVC với xác nhận dữ liệu chú thích, với mặc định ràng buộc, với Entity Framework 4.0 ... và thất bại khá fantastically, tôi tin.

+3

vì vậy bạn có một tài sản được gọi một db? người điên, đặt nó vào một phương pháp. – RPM1984

+0

getter của bạn là quá phức tạp cho một tài sản. – dtb

+0

Tôi đồng ý với hai ý kiến ​​ở trên, và có thực sự khó khăn như vậy khi chỉ viết bản thân mình? Những người tings mọi người lo lắng về tôi ngạc nhiên ... –

Trả lời

4

Câu trả lời này rộng hơn một chút so với việc loại bỏ bộ đặt trên thuộc tính - kết hợp nó với phần còn lại của câu trả lời và nhận xét, và lấy các bit có lý. Hy vọng rằng các bit ở cuối sẽ giúp quá, có thể chỉ cần không phải ngay bây giờ.

Nếu bạn đang sử dụng này trong một mô hình dữ liệu cho mục đích ràng buộc và do đó muốn nó tiếp xúc như một tài sản, tôi sẽ làm một cái gì đó như thế này:

public class BookModel 
{ 
    public IList<int> AuthorIds { get; set; } 
} 

Thực hiện một dịch vụ mà bạn sẽ gọi để cư trú của bạn mô hình:

public class BookService() 
{ 
    public List<int> GetAuthorIDs(int bookId) 
    { 
     var authorIds = new List<int>(); 
     using (var context = new GarbageEntities()) 
     { 
      foreach (var author in context.Authors.Where(
       a => a.Books.Any(b => b.BookID == bookId))) 
      { 
       authorIds.Add(author.AuthorID); 
      } 
     } 
     return authorIds; 
    } 
} 

Trong điều khiển của bạn:

public ViewResult List(int id) 
{ 
    var model = new BookModel 
    { 
     AuthorIds = service.GetAuthorIDs(id) 
    }; 

    return View(model); 
} 

tôi một cách rõ ràng nơi ẩn náu không bao gồm làm thế nào để nhanh chóng dịch vụ cuốn sách trong bộ điều khiển. Sở thích của tôi là tiêm nó vào thời gian chạy trong một hàm tạo, nhưng điều này sẽ yêu cầu bạn phải có một nhà máy điều khiển tùy chỉnh - một bước tại một thời điểm. Bạn có thể chỉ mới nó lên trong constructor mặc định: Tôi

private readonly BookService service; 

public BookController() 
{ 
    service = new BookService(); 
} 

Trong một thế giới lý tưởng, mặc dù sẽ làm điều này:

private readonly BookService service; 

public BookController(BookService service) 
{ 
    if(service == null) 
     throw new ArgumentException("service must be supplied"); 

    this.service = service; 
} 

Tuy nhiên các nhà máy điều khiển MVC mặc định hy vọng bộ điều khiển để có một tham số mặc định, do đó, làm điều đó với việc xây dựng tiêm sẽ mất nhiều công việc hơn một chút.

+0

Cảm ơn bạn đã dành thời gian để hiển thị tất cả mã này. – asfsadf

+2

+1 cho ví dụ về mã. Lưu ý: ToList() là dư thừa trong vòng lặp GetAuthorIDs foreach. –

+0

Cảm ơn - đã cập nhật. –

7

Không, không thể. Mọi thứ đều rõ ràng hoặc toàn bộ thuộc tính là tự động. Dù sao, trong trường hợp đó setter dường như không thực hiện bất kỳ ý nghĩa ... không nên có setter ở tất cả.

Ngoài ra, tôi nghĩ bạn nên làm cho nó trở thành một phương pháp. Nó sẽ làm cho nó rõ ràng hơn cho người gọi rằng nó thực hiện một tính toán có thể lenghty. Nó cũng chống lại các hướng dẫn để thực hiện xử lý phức tạp trong một thuộc tính.

+0

Xin lỗi vì sự thiếu hiểu biết của tôi, nhưng loại phương pháp nào được khuyến nghị trong trường hợp này? – asfsadf

+0

Um, một trong số đó nằm trong DAL? – RPM1984

+0

"Danh sách công khai GetAuthorIDs()" triển khai mã chính xác bạn đã có :-) – Carson63000

2

nếu bạn muốn làm điều đó theo cách của bạn, chỉ cần làm như sau:

private List<int> authorIDs; 
public List<int> AuthorIDs 
{ 
    get 
    { 
     var l = new List<int>(); 
     using (var context = new GarbageEntities()) 
     { 
      foreach (var author in context.Authors.Where(a => a.Books.Any(b => b.BookID == this.BookID)).ToList()) 
      { 
       l.Add(author.AuthorID); 
      } 
     } 
     return l; 
    } 

    set{authorIDs = value; //this does not make much sense though ... what are you trying to do by setting authorIDs? 
} 
} 

nhưng cũng giống như những người khác đang nói, đây là một quá mức cần thiết cho một tài sản, đặt nó trong phương pháp này, một cái gì đó giống như

public List<int> GetAuthorIDs(int bookId) 
    { 
      var l = new List<int>(); 
      using (var context = new GarbageEntities()) 
      { 
       foreach (var author in context.Authors.Where(a => a.Books.Any(b => b.BookID == bookId)).ToList()) 
       { 
        l.Add(author.AuthorID); 
       } 
      } 
      return l; 
     } 
+1

Điểm thiết lập trường bạn không bao giờ sử dụng là gì? Thực hiện một setter rỗng, hoặc tốt hơn: không có setter ở tất cả ... –

+0

@Thomas: chỉ cần thêm một bình luận nói chính xác rằng :) –

+0

Tôi đã cố gắng tận dụng lợi thế của các ràng buộc tự động trong khuôn khổ MVC. Đó là lý do duy nhất. – asfsadf

3

Các setter mặc định sẽ tạo ra một biến sự ủng hộ tại thời gian biên dịch với một tên như sau:

[CompilerGenerated] 
private string <AuthorIDs>k__BackingField; 

Vì điều này được tạo tại thời gian biên dịch, nó không thể được tham chiếu trong mã của bạn cho đến khi nó được tạo ra, và ngoài ra, các dấu ngoặc nhọn (cố ý) không được phép trong các tên biến.

Vì lý do này, nó sẽ là vô dụng để cho phép một thứ gì đó được lưu trữ trong biến này (mà về bản chất là bộ tự động làm) không có cách nào truy cập vào giá trị này tại bất kỳ thời điểm nào trong tương lai (sau tất cả getter ở đây không phải là một getter tự động nó sẽ trả lại một cái gì đó hoàn toàn khác nhau)

Vì vậy, để summerise, mà không có một getter, sẽ (đó là cách duy nhất để lấy giá trị từ biến ủng hộ này) sẽ không có điểm trong việc thiết lập riêng tư

+0

Cảm ơn bạn đã giải thích này. – asfsadf

0

Có thực sự là một cách để làm điều đó:

public List<int> AuthorIDs 
{ 
    get 
    { 
     var l = new List<int>(); 
     using (var context = new GarbageEntities()) 
     { 
      foreach (var author in context.Authors.Where(a => a.Books.Any(b => b.BookID == this.BookID)).ToList()) 
      { 
       l.Add(author.AuthorID); 
      } 
     } 
     return l; 
    } 
    set{ 
     this.SetPropertyValue(page => page.AuthorIDs, value); 
    } 
} 
Các vấn đề liên quan