3

我正在尝试使用以下 getter 和 setter 创建属性 i。我试过了:

    int i { 
        get{
            return i;   
        }
        set {
            if (value > 60) {
            } else { 
                i = value; 
            } 
        }

    }

但是,当我尝试此操作时,当我尝试运行代码时会出现堆栈溢出错误。我的代码有什么问题吗?任何 Assistane 将不胜感激。

4

5 回答 5

5

如果您的属性中有任何类型的逻辑(否则自动属性是要走的路),您需要一个支持字段 - 目前您正在分配给属性本身,它再次调用您的 setter 代码(同样适用于 getter) - 这会导致堆栈溢出异常。

例子:

private int _i;
public int SomeProperty
{
  get{ return _i;}
  set 
  {
     //your logic here
     _i = value; 
  }
}
于 2012-10-06T04:49:14.170 回答
4

做这个:

private int i; // backing field

int I
{ 
    get
    {
        return i;   
    }
    set
    {
        if (value > 60) {
        } else
        { 
            i = value; 
        } 
    }
}

如果您不这样做,您的代码将保持循环状态,从而导致StackOverflow错误。

于 2012-10-06T04:49:51.153 回答
2

它是这样的

private int i = 0;
public int I
{
    get
    {
        return i;
    }
    set
    {
        if (value > 60)
        {
        }
        else
        {
            i = value;
        }
    }
}

请遵循一些编码命名约定

  1. 属性是类似于 MyProperty 的 PascalCase
  2. 私有字段是骆驼案例,如 localVariable

更多请阅读这里

于 2012-10-06T04:51:31.700 回答
1

只需使用这段代码:

int i;

public int I 
{ 
    get { return i; }
    set { if (value <= 60) i = value; } 
}

您的代码中的问题是您在属性中指定了 i,该属性在 getter/setter 的主体内引用自身,变成循环效果,最终导致 StackOverflow 错误。

于 2012-10-06T04:54:42.957 回答
1
int i { 
    get{
        return i;   
    }
    set {
        ...
        i = value; 
        ...
    }
}

在上面的代码中,您在 get 和 set 块中使用相同的属性名称。

编译后,您的代码将被翻译成与此等效的内容:

int get_i()
{
 return get_i();
}

void set_i(int value)
{
 set_i(value);
}

如您所见,它们中的每一个都将无限调用自身(递归)而没有任何退出条件,从而导致StackOverflow异常。

如果你有一个属性的支持字段,就像这个问题的其他答案所建议的那样,编译器会生成一些与此等效的东西,它没有递归:

int get_i()
{
 return _i; //_i is the backing field
}

void set_i(int value)
{
 _i = value;
}

更新:

为了完整起见,我在这里添加了一种解决您问题的方法。

int _i;
int i { 
    get{
        return _i;   
    }
    set {
        if (value > 60) {
        } else { 
            _i = value; 
        } 
    }
}
于 2012-10-06T06:07:52.203 回答