gpt4 book ai didi

c# - 尝试使用参数启动 PointF

转载 作者:太空宇宙 更新时间:2023-11-03 13:40:55 25 4
gpt4 key购买 nike

编辑:谢谢大家,伙计们。我很感激你。

我正在开发一个在两个值之间绘制函数的程序。这是代码:

public partial class Form2 : Form
{
public class E
{
public static double A;
public static double B;
public static double C;
public static int s1;
public static int s2;
public static int K=(s2 - s1) * 18;
}

public Form2(double a, double b, double c, double s1, double s2)
{
InitializeComponent();
E.A = a;
E.B = b;
E.C = c * 1.3333;
E.s1 = Convert.ToInt32(s1);
E.s2 = Convert.ToInt32(s2);

this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

Calc();
}

public PointF[] p = new PointF[E.K]; //Value in E.K isn't applied here :(

private void Calc()
{
for (int x = 18 * E.s1; x < 18 * E.s2; x++)
{
double res = (E.A * Math.Pow(x, E.B) + E.C);
p[x - 18 * E.s1] = new PointF(x, (float)res);
}
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
float Y = (float)E.C;
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.TranslateTransform(203, 203 + 14 * (-Y));
if (E.B == 0 || E.B == 1)
{
e.Graphics.ScaleTransform(1, -1F);
}
else
{
e.Graphics.ScaleTransform(1F, -0.05F);
}

e.Graphics.DrawLines(Pens.Blue, p);

}

我做了一些分析,发现当 E.K 进入 PointF 函数时,它变成了 0,因此程序给出了 IndexOutOfRangeException .你们有什么建议或替代想法吗?

最佳答案

这与对象构造/初始化的顺序有关。问题是 E.s1E.s2 未初始化,因此请考虑以下事项:

public class E
{
...
public static int s1;
public static int s2;
public static int K=(s2 - s1) * 18;
}

// outside of a constructor
public PointF[] p = new PointF[E.K];

public Form2(double a, double b, double c, double s1, double s2)
{
// inside the constructor
E.s1 = Convert.ToInt32(s1);
E.s2 = Convert.ToInt32(s2);
}

静态字段初始化器在类型初始化器之前执行,实例初始化器在构造函数之前执行。因此,当创建 Form2 的新实例时,会发生以下情况:

  1. 初始化 Form2 的所有静态字段,如果有(但没有)。
  2. 调用 Form2 的类型初始值设定项,如果有的话(但没有)
  3. 初始化 Form2 的所有实例字段(如果有的话)。
    • 初始化 p 但由于它使用 E.K,此时它初始化 E 类。
      1. 初始化 E 的所有静态字段,如果有的话:
      2. K = (s2 - s1) * 18 但由于 s1s2 未初始化,因此计算结果为 K = 0
      3. 调用 E 的类型初始值设定项,如果有(但没有)
  4. 调用 Form2 的构造函数,如果有的话
    • E.s1 = Convert.ToInt32(s1);E.s2 = Convert.ToInt32(s2);
      但此时这对 p 没有任何影响,因为它已经被初始化了。

这可能会让人感到困惑和棘手。因此,强烈建议您避免使用这种结构。使用构造函数控制创建实例成员的顺序,使用类型初始值设定项控制创建实例成员的顺序。此外,避免使用静态字段作为属性的简单抓包,尤其是当这些属性在程序的生命周期中发生变化时。我建议将您的类(class)重构为如下内容:

public class E
{
public double A;
public double B;
public double C;
public int s1;
public int s2;
public int K { get { return (s2 - s1) * 18; } }
}

private E e;
private PointF[] p;

public Form2(double a, double b, double c, double s1, double s2)
{
...
e = new E();
e.A = a;
e.B = b;
e.C = c * 1.3333;
e.s1 = Convert.ToInt32(s1);
e.s2 = Convert.ToInt32(s2);
p = new PointF[e.K];
...
}

private void Calc()
{
for (int x = 18 * e.s1; x < 18 * e.s2; x++)
{
double res = (e.A * Math.Pow(x, e.B) + e.C);
p[x - 18 * e.s1] = new PointF(x, (float)res);
}
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
float Y = (float)this.e.C; // this.e avoids confusion with parameter e
...
}

当然E类现在有些多余,它的所有字段都可以直接存储在Form2中,但这至少使它更容易通过如果需要,将所有这些字段分配给另一个类(这可能是您首先选择使用静态的原因)。

我还建议为类或字段使用多于一两个字符的名称。这使得很难判断代码的用途。

关于c# - 尝试使用参数启动 PointF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17077696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com