能否在公共属性的setter方法中引用自身?如何避免此类实现引发的栈溢出?
解决C#属性栈溢出问题,同时保留简洁的表达式体写法
嘿,这个问题我太熟了!你精准地找到了问题根源——你的someString属性在get和set访问器里直接引用了自身,导致每次调用都会触发无限递归,最终栈溢出。当然可以保留类似的简洁实现,下面给你两种靠谱的方案:
方案1:手动添加私有后备字段(保留表达式体写法)
这是最直观的解决方式,我们给属性加一个专门的私有存储字段,让get和set访问器操作这个字段而不是属性自身:
public class SomeClass { // 私有后备字段,按照C#命名约定用下划线开头区分属性 private string _someString; // 注意构造函数名要和类名大小写一致,C#是大小写敏感的! public SomeClass() { _someString = "ABC"; } // 表达式体的get和set,现在指向后备字段,避免递归 public string SomeString { get => _someString; set => _someString = value; } }
这样修改后,get访问器返回的是私有字段_someString的值,set访问器把传入的value赋值给这个字段,完全不会触发递归,同时你想要的简洁表达式体写法也保留下来了。如果之后需要在get/set里加额外逻辑(比如验证输入的字符串不为空),这种写法也方便扩展。
方案2:使用自动属性(更简洁的写法)
如果你的属性不需要自定义的get/set逻辑,直接用C#的自动属性就好——编译器会自动帮你生成隐藏的私有后备字段,写法更短,还能彻底避免手动写递归的问题:
public class SomeClass { // 自动属性,编译器自动生成私有后备字段 public string SomeString { get; set; } public SomeClass() { SomeString = "ABC"; } }
这种写法的效果和方案1完全一样,只是把后备字段的创建交给了编译器。之后如果需要扩展get/set逻辑,再改成方案1的手动后备字段写法也很轻松。
另外提个小细节:你原来的代码里构造函数名someclass和类名someClass大小写不一致,这在C#里会编译报错,记得改成一致的(按照约定,类名和属性名都用帕斯卡命名法,也就是首字母大写)。
内容的提问来源于stack exchange,提问作者SomeName
相关产品推荐
相关产品推荐

