在非默认结构构造函数中调用结构方法

时间:2009-11-04 05:43:38

标签: c#

我有一个非常简单的例子,我用它来学习C#中的结构:

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);
        }
    }
}

我在“ERROR HERE”注释行中收到此错误:

  

在将所有字段分配给

之前,不能使用'this'对象

在非默认构造函数中调用结构方法为结构成员赋值是不合法的吗?

4 个答案:

答案 0 :(得分:5)

您可以将这些方法设置为静态,但它可以正常工作,但在分配完所有字段之前,您无法调用非静态方法。

答案 1 :(得分: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);
        }
    }
}

答案 2 :(得分:2)

GBegen有正确的想法 - 使范围检查方法保持静态。

这不仅会解决问题,而且会使代码更加清晰:方法根本不依赖于结构的状态,而且它们不是多态的,所以它们不应该是实例方法。

答案 3 :(得分:1)

您可以在验证输入之前将每个字段设置为零。这是有道理的,因为默认的构造函数无论如何都会将它们设置为零,所以这是一个必须在你的程序中处理的情况。设置值后,即使在构造函数中也可以调用所需的任何方法。

但正确的解决方案是其他人都在说的:让范围检查静态方法。事实上,在这种情况下,它们是纯函数(没有副作用,仅对参数而不是静态或实例字段进行操作)。纯函数始终是静态的。从调试,多线程,性能等角度来看,静态纯函数是巧克力覆盖的 - 很棒。