Вызов метода структуры внутри конструктора структуры не по умолчанию

2

У меня есть этот очень простой пример, который я использую для изучения структур на С#:

struct ScreenPosition
{
    // These are the two private members of the structure 
    private int x; 
    private int y;

    private int RangeCheckedX(int xPos)
    {
        if (xPos < 0 || xPos > 1280)
        {
            throw new ArgumentOutOfRangeException("X");
        }
        return xPos;
    }

    private int RangeCheckedY(int yPos)
    {
        if (yPos < 0 || yPos > 1024)
        {
            throw new ArgumentOutOfRangeException("Y");
        }
        return yPos;
    }

    // Declaring the non-default constructor
    public ScreenPosition(int X, int Y)
    {
        this.x = RangeCheckedX(X); // ERROR HERE
        this.y = RangeCheckedY(Y); // ERROR HERE
    }

    // Declaring  the property X - Follows a syntax. See the C# quick reference sheet 
    public int X
    {
        get
        {
            return this.x;
        }

        set
        {
            this.x = RangeCheckedX(value);
        }
    }
    // Declaring  the property X - Follows a syntax. See the C# quick reference sheet 
    public int Y
    {
        get
        {
            return this.y;
        }

        set
        {
            this.y = RangeCheckedY(value);
        }
    }
}

Я получаю эту ошибку на строках комментариев "ОШИБКА ЗДЕСЬ":

Объект 'this' не может использоваться до того, как все его поля будут присвоены

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

  • 1
    Проверьте это также: jaggersoft.com/pubs/StructsVsClasses.htm Я узнал больше о структурах за две минуты, чем когда-либо думал.
  • 3
    Вы создаете изменчивую структуру. Я бы переосмыслил этот дизайн.
Теги:

4 ответа

5
Лучший ответ

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

2

GBegen имеет правильную идею - ставьте методы проверки диапазона.

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

  • 0
    Большое спасибо. Ваше объяснение было наиболее «усваиваемым».
2

Нельзя вызывать методы для структур, пока не будут заполнены все поля (свойства).

Я знаю его взломать, но это сработает.

 struct ScreenPosition
{
    // These are the two private members of the structure 
    private int x;
    private int y;

    private int RangeCheckedX(int xPos)
    {
        if (xPos < 0 || xPos > 1280)
        {
            throw new ArgumentOutOfRangeException("X");
        }
        return xPos;
    }

    private int RangeCheckedY(int yPos)
    {
        if (yPos < 0 || yPos > 1024)
        {
            throw new ArgumentOutOfRangeException("Y");
        }
        return yPos;
    }

    // Declaring the non-default constructor
    public ScreenPosition(int X, int Y)
    {
        this.x = X; 
        this.y = Y; 
        this.x = RangeCheckedX(X);
        this.y = RangeCheckedY(Y);
    }

    // Declaring  the property X - Follows a syntax. See the C# quick reference sheet 
    public int X
    {
        get
        {
            return this.x;
        }

        set
        {
            this.x = RangeCheckedX(value);
        }
    }
    // Declaring  the property X - Follows a syntax. See the C# quick reference sheet 
    public int Y
    {
        get
        {
            return this.y;
        }

        set
        {
            this.y = RangeCheckedY(value);
        }
    }
}
  • 0
    Это будет работать, но создание статичных методов является менее хакерским подходом IMO.
1

Вы можете установить каждое из полей в ноль перед проверкой входов. Это имеет смысл, потому что конструктор по умолчанию будет устанавливать их в ноль в любом случае, так что случай, который должен быть обработан в вашей программе, в любом случае. Как только значения установлены, вы можете вызывать любые методы, которые вы хотите, даже в конструкторе.

Но правильное решение - это то, что говорят все остальные: заставляйте диапазон проверять статические методы. Фактически, в этом случае они являются чистыми функциями (без побочных эффектов и работают только по параметрам, а не по статичным или по экземплярам). Чистые функции всегда могут быть статическими. А статические чистые функции покрыты шоколадом - потрясающие с точки зрения отладки, многопоточности, производительности и т.д.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню