Ошибка переполнения стека в C # - но как это исправить? - PullRequest
5 голосов
/ 27 октября 2010

Я столкнулся с действительно интересной ошибкой во время выполнения, которая приводит к переполнению стека.

Я определил структуру следующим образом:

public enum EnumDataType { Raspberry, Orange, Pear, Apple };

public class DataRequest
{
    public long DataSize 
    { 
        get { return 0; } 
        set { DataSize = value; } 
    }

    public EnumDataType DataType  
    { 
        get { return EnumDataType.Apple; } 
        set { DataType = value; } 
    }
}

Прекрасно работают следующие строки:

DataRequest request = new DataRequest();
request.DataSize = 60;

Однако, когда я перехожу через следующую строку в коде, он генерирует переполнение стека:

request.DataType = EnumDataType.Raspberry;

Конечно, я могу исправить это, удалив значения по умолчанию или используя auto get / set, но мне нужно, чтобы он был и читаемым, и записываемым, и возвращал значение по умолчанию - есть идеи?

Ответы [ 5 ]

19 голосов
/ 27 октября 2010
public long DataSize { get { return 0; } set { DataSize = value; } } 

Вы постоянно устанавливаете значение DataSize.Вам нужно создать локальную переменную и использовать ее вместо этого.например,

private long dataSize;

public long DataSize
{
    get { return this.dataSize; }
    set { this.dataSize = value; }
}

РЕДАКТИРОВАТЬ Я написал DataSize, но то же самое относится к DataType

12 голосов
/ 27 октября 2010

Как уже говорили другие, переполнение стека происходит из-за того, что ваш установщик свойств просто вызывает себя.Может быть проще понять, если вы думаете об этом как о методе:

// This obviously recurses until it blows up
public void SetDataType(long value)
{
    SetDataType(value);
}

Насколько я понимаю, вы пытаетесь создать обычные свойства, но со значением по умолчанию, верно?

В этом случае вам нужны вспомогательные переменные, которые устанавливаются установщиками - и получатели также должны возвращать эти переменные.Это переменные , которые должны получить значения по умолчанию:

private long dataSize = 0;
public long DataSize {
  get { return dataSize; }
  set { dataSize = value; }
}

private EnumDataType dataType = EnumDataType.Apple;
public EnumDataType DataType { 
  get { return dataType; }
  set { dataType = value; }
}

Либо использовать автоматические свойства, но установить значения по умолчанию в конструкторе:

public long DataSize { get; set; }
public EnumDataType DataType { get; set; }

public DataRequest()
{
    DataSize = 0; // Not really required; default anyway
    DataType = EnumDataType.Apple;
}
4 голосов
/ 27 октября 2010
Переполнение стека

происходит потому, что в установщике вы устанавливаете для свойства значение (т. Е. Вы пытаетесь получить что-то, чтобы установить себя в нечто ..., что вызывает бесконечный цикл) ... что означает, что оно пытается установить само значение, которое означает, что его пытается установить себе значение до бума

ваши свойства никогда не получат значения, которые вы устанавливаете, потому что они всегда возвращают одно и то же значение (не сохраненное значение)

public enum EnumDataType { Raspberry, Orange, Pear, Apple }; 

public class DataRequest 
{ 
private long _dataSize = 0;
private EnumDataType _dataType = EnumDataType.Apple;

public long DataSize { get { return _dataSize ; } set { _dataSixe= value; } } 
public EnumDataType DataType  { get { return _dataType; } set { _dataType= value; } } 
} 

это то, что вы действительно хотели

3 голосов
/ 27 октября 2010

Вы должны реализовать его с помощью резервного хранилища:

private EnumDataType dataType;
public EnumDataType DataType  { get { return EnumDataType.Apple; } set { dataType = value; } }

}

Это следует делать каждый раз, когда вы выполняете некоторые действия в методах получения и установки.Кстати, почему вы можете даже установить переменные?вы не можете прочитать их, вы всегда получаете EnumDataType.Apple.Если вы хотите начальное значение, вы можете сделать так:

private EnumDataType dataType = EnumDataType.Apple;
public EnumDataType
{
   get
   {
       return dataType;
   }
   set
   {
       dataType = value;
   }
 }
2 голосов
/ 27 октября 2010

Я не понимаю, как в первой строке: request.DataSize = 60;

Не вызывает переполнения стека - мой совет будет использовать свойства поддержки:

public class DataRequest
{
    protected int dataSize = 0;
    protected EnumDataType enumDataType;
    public long DataSize { get { return 0; } set { dataSize = value; } }
    public EnumDataType DataType  { get { return EnumDataType.Apple; } set { enumDataType = value;} 
}
...