2010-07-18 31 views
7

Đây là đơn giản để giải thích: làm việc nàystack overflow ngoại lệ trong C# setter

using System; 
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>; 

namespace ConsoleApplication2 
{ 
    class test 
    { 
     public ConstraintSet a { get; set; } 
     public test() 
     { 
      a = new ConstraintSet(); 
     } 
     static void Main(string[] args) 
     { 
      test abc = new test(); 
      Console.WriteLine("done"); 
     } 
    } 
} 

này không

using System; 
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>; 

namespace ConsoleApplication2 
{ 
    class test 
    { 
     public ConstraintSet a { get { return a; } set { a = value; } } 
     public test() 
     { 
      a = new ConstraintSet(); 
     } 
     static void Main(string[] args) 
     { 
      test abc = new test(); 
      Console.WriteLine("done"); 
     } 
    } 
} 

tôi nhận được một ngoại lệ stack overflow trên của setter trong lớp thứ hai và tôi làm không biết tại sao. Tôi không thể sử dụng biểu mẫu đầu tiên bởi vì nó không được hỗ trợ bởi công cụ thống nhất

+0

'Tôi không thể sử dụng các hình thức đầu tiên bởi vì nó không được hỗ trợ bởi sự hiệp nhất engine' ... Các hình thức đầu tiên là viết tắt trình biên dịch cấp. Nó sẽ làm việc tốt với động cơ thống nhất. – SLaks

+1

bản sao có thể có của [StackOverFlow trên thuộc tính lớp] (http://stackoverflow.com/questions/680765/stackoverflow-on-class-property) và nhiều người khác. –

+0

nope, unity C# compiler không hỗ trợ cú pháp này – Patrik

Trả lời

24

Khi bạn viết a = value, bạn sẽ gọi lại trình thiết lập thuộc tính.

Để sử dụng tính không tự động, bạn cần phải tạo ra một lĩnh vực sao lưu tin riêng biệt, như thế này:

ConstraintSet a; 
public ConstraintSet A { get { return a; } set { a = value; } } 
+1

Không chắc tại sao câu trả lời này lại bị downvoted, cho rằng nó có nhiều thông tin hơn về Cory Larson ... –

+0

@Jon: Tôi rất ngạc nhiên khi tôi có bất kỳ phiếu bầu nào khi đăng giây sau bạn: P. Tôi đã quá lờ mờ sáng nay để giải thích lý do tại sao **, do đó, không có nghi ngờ cả hai SLaks và câu trả lời của bạn là tốt hơn. –

+0

@Cory: Tôi không có gì đặc biệt chống lại câu trả lời của bạn, trong đó nó đã giải quyết được vấn đề - nhưng không có lý do tại sao. Có thể ai đó chỉ không thích những người có đại diện cao. –

15

Bạn chưa tuyên bố một biến sự ủng hộ - bạn vừa nhận được một tài sản mà getters và setters tự gọi mình. Nó không rõ ràng với tôi tại sao hình thức đầu tiên không được hỗ trợ bởi Unity - có nghĩa là nó có thể là tương đương sẽ không được hỗ trợ một trong hai, nhưng đó là về cơ bản này:

private ConstraintSet aValue; 
public ConstraintSet a { get { return aValue; } set { aValue = value; } } 

Tôi thường muốn có một tên thường hơn, dĩ nhiên - có nghĩa là bạn có thể lấy đi mà không có "chút giá trị`:

private ConstraintSet constraints; 
public ConstraintSet Constraints 
{ 
    get { return constraints; } 
    set { constraints = value; } 
} 

để cung cấp cho một chút chi tiết hơn là tại sao hình thức thứ hai hiện tại của bạn là ném một StackOverflowException, bạn nên luôn luôn nhớ rằng Các thuộc tính cơ bản của bạn là ngụy trang. Mã bị hỏng của bạn trông giống như sau:

public ConstraintSet get_a() 
{ 
    return get_a(); 
} 

public void set_a(ConstraintSet value) 
{ 
    set_a(value); 
} 

Hy vọng điều đó rõ ràng lý do tại sao phiên bản đó đang thổi ngăn xếp. Phiên bản sửa đổi chỉ đặt một biến thay vì gọi bất động sản một lần nữa, vì vậy nó trông như thế này khi mở rộng:

private ConstraintSet aValue; 

public ConstraintSet get_a() 
{ 
    return aValue; 
} 

public void set_a(ConstraintSet value) 
{ 
    aValue = value; 
} 
+0

@Downvoter: Chăm sóc để đưa ra lý do? –

+0

chỉ đơn giản là sự thống nhất C# trình biên dịch không hỗ trợ những gì hình ảnh C# nào. điều này là bởi vì nó có khả năng tương thích với mono – Patrik

+0

@Patrik: Mono cũng hỗ trợ C# 3 ... C# 3 đã xuất hiện gần 3 năm nay; đây không phải là một tính năng mới. –

3

Bạn cần một biến sự ủng hộ tư nhân trong tài sản công cộng của bạn:

private ConstraintSet _a; 
public ConstraintSet a { get { return _a; } set { _a = value; } } 
3

Bạn không thể sử dụng cùng tên biến bên trong getter và setter.
Điều này sẽ khiến nó tự gọi và cuối cùng sẽ ngăn xếp luồng. Quá nhiều đệ quy.
Bạn sẽ cần một biến sự ủng hộ:

private ConstraintSet _a; 
public ConstraintSet a { get { return _a; } set { _a = value; } }