2013-04-22 22 views
5
public int Position 
{ 
    get 
    { 
     if (Session["Position"] != null) 
     { 
      Position = Convert.ToInt32(Session["Position"]); 
     } 
     else 
     { 
      Position = 5; 
     } 
     return Position; 
    } 
    set 
    { 
     Position = value; 
    } 
} 

chương trình của tôi gọi là get và đi vào nếu vòng lặp và sau đó chạy infitely vào mã bộTôi nhận được vào vòng lặp vô hạn trong setter tài sản

+0

@ Knaģis có mã được sửa, nhưng để giải thích thêm lý do: Hãy nghĩ về các getters và setters này như các hàm vì đó là những gì chúng ở đằng sau hậu trường. Nếu một hàm gọi chính nó bên trong, không có phương tiện để thoát, bạn sẽ ở trong một vòng lặp vô hạn. – bland

Trả lời

13

Lỗi này là bởi vì trong bạn set {} bạn đang gọi setter cùng đệ quy .

mã đúng sẽ

private int _position; 
public int Position 
{ 
    get 
    { 
     if (Session["Position"] != null) 
     { 
      this._position = Convert.ToInt32(Session["Position"]); 
     } 
     else 
     { 
      this._position = 5; 
     } 
     return this._position; 
    } 
    set 
    { 
     this._position = value; 
    } 
} 
+3

Bạn không thực sự cần gạch dưới và 'này' cùng một lúc. Hầu hết mọi người sẽ nhận thấy rằng dấu gạch dưới có nghĩa là bạn đang đề cập đến một thành viên địa phương, và không có gì cần phải được định hướng. –

+0

Dấu gạch dưới thực sự chỉ là một vấn đề của thói quen đối với tôi (và nhiều người khác), nhưng theo ý kiến ​​của tôi (và cũng StyleCop http://stackoverflow.com/questions/1562540/why-does-stylecop-recommend-prefixing-method- hoặc-property-calls-with-this) 'this' phải là bắt buộc luôn. –

+2

Vâng, StyleCop đã sai. :) Và câu hỏi Stack Overflow đó có [ý kiến ​​bất đồng ý kiến] (http://stackoverflow.com/a/1562571/102937). –

4

Sử dụng một biến thành viên hoặc có lẽ lưu nó trong phiên.

private int _position; 
public int Position 
{ 
    get 
    { 
     if (Session["Position"] != null) 
     { 
      _position= Convert.ToInt32(Session["Position"]); 
     } 
     else 
     { 
      _position= 5; 
     } 
     return _position; 
    } 
    set 
    { 
     _position = value; 
    } 
} 
2

Không có gì đặc biệt giống như chuỗi về các mục trạng thái phiên.

Tại sao bạn sẽ không chỉ cần làm theo các nguyên tắc KISS và làm điều gì đó như

public int Position 
{ 
    get { return (int) (Session["Position"] ?? 5) ; } 
    set { Session["Position"] = value ;    } 
} 

hoặc (tùy thuộc vào yêu cầu thực tế/specs của bạn:

public int Position 
{ 
    get { return Session["Pointer"] as int? ?? position ?? 5 ; } 
    set { position = value ; } 
} 
private int? position ; // backing store 
+0

là 'int'? 'int' là kiểu giá trị, làm thế nào nó có thể là' as'? –

+0

@KenKin: 'int? 'Là cú pháp đường cho' Nullable ', một loại tham chiếu (và đặc biệt, để khởi động). Một 'int' thẳng sẽ được đóng trong cửa hàng phiên; một 'int?' là cho tất cả các ý định và mục đích, đã được đóng hộp. Xem thông số kỹ thuật, ISO 23270 § 14.9.11: * Toán tử as được sử dụng để chuyển đổi một giá trị thành một kiểu tham chiếu hoặc kiểu nullable. Khi chuyển đổi thành kiểu nullable, toán tử as sử dụng chuyển đổi gói, chuyển đổi unboxing, hoặc vô hiệu hóa loại chuyển đổi (§13.7.1) ... nếu chuyển đổi được chỉ định là không thể, giá trị kết quả là null. * –

+0

Xin lỗi .. chỉ là một vấn đề dễ đọc .. –

1

Một tính chất sở hữu tính năng tự động thực hiện bao gồm Nếu bạn tự viết mã, một trường có thể không cần thiết.

getter của bạn gọi setter, và setter gọi thiết lập ter; đó sẽ là đệ quy vô hạn. Bạn có thể cần một trường để lưu trữ Position.

Tuy nhiên, nếu chúng tôi thay đổi nó bằng cách lưu trữ vào một trường và trình thiết lập thực tế không có hiệu lực. Vì vậy, mã có thể được thay đổi thành:

public int Position { 
    set { 
    } 

    get { 
     int x; 
     return (x=Convert.ToInt32(Session["Position"]))>0?x:5; 
    } 
} 

Bạn không cần phải kiểm tra giá trị rỗng, Convert.ToInt32(null) bằng không.