StackOverflowExeption 在您的 sn-p 中是不可避免的,这就是原因。
要理解这一点,我们必须知道什么是属性以及我们使用它们的原因。基本上,属性是一组方法,它不是一个字段。通过“属性”,我们表示 set 方法(设置某物的值)和 get 方法(返回某物的值)的集合。
在借助上述方法为私有字段赋值时,属性为我们提供了一定程度的灵活性。
您的代码不起作用,因为您通过一次又一次调用 get 方法溢出堆栈,这就像一个没有任何退出条件的递归函数(当我们尝试获取 FirstName 的值时,该属性调用它的 get 方法,它返回itsels,然后再次调用get,再次调用get,再一次,再一次,再一次,你的堆栈被这些东西填满了)。
如果你的类中有一个私有字段,你可以使用该字段周围的属性来公开它,我们可以为 get 和 set 方法添加额外的处理,这里是一个例子:假设我们想要获取 ascii 代码一个数字(0 到 9),我们可以为此使用一个属性(这不是最好的例子,只是为了说明一些属性的使用):
// this is the private field that we do not want to expose (aka to make
// it accessible for everyone
private int digit;
// But we want somehow to allow users of our class to interact
// with the digit field, so we create a property.
// Note: fields' name start with lowercase, properties' name with Uppercase
public int Digit
{
get
{
// this is the method that gets calls whenever the user calls Digit,
// Example: Console.WriteLine(object.Digit);
// let's add here the logic of getting digit's ascii code
return Char.Parse(digit.ToString());
}
set
{
// this method gets called when someone assigns a value for Digit
// Example: Digit = 3;
// here we can add the validation logic ( 0 <= value <=9)
if(value < 0 || value > 9)
throw new Exception("Please provide a number between 0 and 9");
digit = value;
}
}
当有人访问数字时,我们使用 Digit 属性将数字转换为 ASCII,并验证尝试分配给数字字段的值。
在您的情况下,您可以像这样编写 FirstName 属性:
public string FirstName{ get; set; }
在后台,这条线将被视为:
private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName= value }
}
更详细地说明堆栈溢出的原因。
有许多语言没有像 C# 这样的属性,所以人们只需添加单独的 get 和 set 方法。有了这个模型,就更容易发现溢出发生的位置。假设 C# 中没有属性,因此我们创建了一个私有字段和两个方法 - 一个用于设置,另一个用于获取私有字段的值。
private string firstName;
public string GetFirstName()
{
return firstName;
}
public void SetFirstName(string value)
{
firstName = value;
}
现在他有一个 setter 和 getter,它们没有包含在属性中。要查看问题示例中发生溢出的位置,让我们将其调整到我们没有属性的新环境;
public string GetFirstName()
{
return GetFirstName();
}
public void SetFirstName(string value)
{
GetFirstName() = value;
}
这实际上就是您的代码所做的。没有私人场地可以玩,物业自己玩^^
当我们写这个时:
object.SetFirstName("Rick Astley");
我们进入 SetFirstName 方法,该方法调用 GetFirstName(),voala,死路一条。将“=>”视为“调用”:
SetFirstName("Rick Astley") => GetFirstName() => GetFirstName() => ...