避免直接使用数字

时间:2018-05-30 08:47:03

标签: c# class numbers

我正在开展一个涉及来自相机的图像的项目。我创建了一个新的class,我在其中定义了一个方法,我可以调用该方法从图像中提取数据。以下是class的代码:

class DataFromBitmap
{
    static public Bitmap ImageToTreat; 
    double[] ValeurPixelsExperiment = new double[132];
    double[] ValeurPixelsReference = new double[132];
    double[] ValeurPixelsSumExperiment = new double[1024];
    double[] ValeurPixelsSumReference = new double[1024];
    int[] PixelColorCount = new int[256];
    int[] PixelColorCountReady = new int[256];

    /// <summary>
    /// Retrieves data from an input bitmap. Retrieved data : Ref and Exp pixel column mean values and count of each color level population. Output : double[1024] under ExpOutput() and RefOutput(), and int[256] under ColorCountOutput
    /// </summary>
    /// <param Bitmap to treat="pImageToTreat"></param>
    public DataFromBitmap(Bitmap pImageToTreat)
    {
        ImageToTreat = pImageToTreat;

        unsafe
        {
            int width = ImageToTreat.Width;
            int height = ImageToTreat.Height;
            int bytesPerPixel = 1;
            int maxPointerLength = width * height * bytesPerPixel;
            int stride = width * bytesPerPixel;
            System.Drawing.Imaging.BitmapData bData = ImageToTreat.LockBits(new System.Drawing.Rectangle(0, 0, ImageToTreat.Width, ImageToTreat.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, ImageToTreat.PixelFormat);
            byte* scan0 = (byte*)bData.Scan0.ToPointer();
            byte B;
            for (int i = 0; i < ImageToTreat.Width; i++)
            {
                for (int j = 157; j < 288; j++)
                {
                    int Pixel = bytesPerPixel * i + stride * j;
                    B = scan0[Pixel + 0];
                    ValeurPixelsExperiment[j - 157] = B;
                    PixelColorCount[B] += 1;
                }
                ValeurPixelsSumExperiment[i] = ValeurPixelsExperiment.Sum() / 131;

                for (int j = 484; j < 615; j++)
                {
                    int Pixel = bytesPerPixel * i + stride * j;
                    B = scan0[Pixel + 0];
                    ValeurPixelsReference[j - 484] = B;
                    PixelColorCount[B] += 1;
                }
                ValeurPixelsSumReference[i] = ValeurPixelsReference.Sum() / 131;
            }
            ImageToTreat.UnlockBits(bData);

            PixelColorCountReady = PixelColorCount.DeepClone();
        }
    }

    public double[] ExpOutput()
    {
        return ValeurPixelsSumExperiment;
    }

    public double[] RefOutput()
    {
        return ValeurPixelsSumReference;
    }

    public int[] ColorCountOutput()
    {
        return PixelColorCountReady;
    }
}

你可以看到它并不复杂。不过我有一个问题。我想在创建数组时避免直接使用数字(1024,256 ......)。我宁愿做这样的事情:

double[] ValeurPixelsSumExperiment = new double[ImageToTreat.Width];

如果我想更改传入图像的大小,这将更加方便。问题是,如果我在DataFromBitmap方法中创建这些数组,那么它们最终将不再存在于Output方法中。

有没有一种方便的方法可以避免在我的情况下使用数字?这个特例只是一个例子,我有几个我想要适应的课程。

非常感谢。

4 个答案:

答案 0 :(得分:1)

您可以将数组的实例化移动到方法DataFromBitmap中。在那里你可以访问位图的大小。

所以你会有类似的东西:

class DataFromBitmap
{
    static public Bitmap ImageToTreat; 
    double[] ValeurPixelsExperiment;
    double[] ValeurPixelsReference;
    double[] ValeurPixelsSumExperiment;
    double[] ValeurPixelsSumReference;
    int[] PixelColorCount;
    int[] PixelColorCountReady;

    /// <summary>
    /// Retrieves data from an input bitmap. Retrieved data : Ref and Exp pixel column mean values and count of each color level population. Output : double[1024] under ExpOutput() and RefOutput(), and int[256] under ColorCountOutput
    /// </summary>
    /// <param Bitmap to treat="pImageToTreat"></param>
    public DataFromBitmap(Bitmap pImageToTreat)
    {
        ValeurPixelsSumExperiment = new double[pImageToTreat.Width];
        ...

答案 1 :(得分:1)

我认为这是完美的情况,您应该使用set方法而不是简单字段来定义属性:

public static Bitmap ImageToTreat {
    set
    {
        ValeurPixelsExperiment = new double[value.Width];
        ImageToTreat = value;
    }
}
public double[] ValeurPixelsExperiment { get; private set; }

请注意,两者都必须static或不是!

您可以将相同的逻辑应用于其余阵列。

答案 2 :(得分:1)

这是一个常见问题,对于此类事物使用类级别或静态类常量是明智的。它允许您在一个地方更改一次

Constants (C# Programming Guide)

  

常量是在编译时已知的不可变值   不改变计划的生命。常量声明为   const修饰符。只有C#内置类型(不包括   System.Object)可以声明为const。有关内置列表   类型,请参阅内置类型表。用户定义的类型,包括   类,结构和数组不能是const。使用readonly   修饰符,用于创建初始化的类,结构或数组   运行时的时间(例如在构造函数中),之后不能   改变了。

如果你想更频繁地更改它们,你也可以将它们放在配置文件中,即缓冲区大小或类似的东西。然而,对于你所描述的常数似乎很合适

答案 3 :(得分:1)

您可以尝试创建一个表示处理输出的类,它将存储所有数组 - 它们具有高内聚性,只要由单个逻辑构建,因此将此关系显式化会更方便。 然后,您不是将数据存储在字段中并使用单独的方法来访问它们,而只是将结果作为此类的实例从您的方法返回 - 在这种情况下,您将能够根据输入创建适当大小的数组。

作为旁注,在构造函数中执行复杂的逻辑并不是一个好主意,从客户的角度来看并不明显。通常,构造者通常只执行构造所需的动作。根据我的提议,您应该将逻辑转换为方法;否则你将无法退货。