字段xxx永远不会分配给,并且始终将其默认值设置为null

谁知道这个问题是什么?

我得到了这个警告, 字段xxx从未被分配给,并且private static Quantizer quantit ; 上将始终具有其默认值null private static Quantizer quantit ;

我不知道该怎么做才能修复,因为当我尝试使用quantit.Quantize()调试说: “对象引用未设置为对象的实例。” 并指向au = quantit.Quantize();

代码:

 public class Quantization : System.Windows.Forms.Form { private static Quantizer quantit; private Button btnLoad; private PictureBox imgPhoto; public Quantization() { btnLoad = new Button(); btnLoad.Text = "&Load"; btnLoad.Left = 10; btnLoad.Top = 10; btnLoad.Click += new System.EventHandler(this.OnLoadClick); imgPhoto = new PictureBox(); imgPhoto.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; imgPhoto.Width = this.Width / 2; imgPhoto.Height = this.Height / 2; imgPhoto.Left = (this.Width - imgPhoto.Width) / 2; imgPhoto.Top = (this.Height - imgPhoto.Height) / 2; imgPhoto.SizeMode = PictureBoxSizeMode.StretchImage; this.Controls.Add(btnLoad); this.Controls.Add(imgPhoto); } protected void OnLoadClick(object sender, System.EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "Open Image"; dlg.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ; if (dlg.ShowDialog() == DialogResult.OK) { Bitmap au; //Image bmp = Image.FromFile("D:\\Documents and Settings\\kiosk.suprisul\\My Documents\\foto1.jpg"); au = quantit.Quantize(); imgPhoto.Image = au; //imgPhoto.Image = bmp; //imgPhoto.Image = au; //new Bitmap(dlg.OpenFile()); } dlg.Dispose(); } [STAThread] static void Main(string[] args) { //Image bmp; //bmp = Image.FromFile("teste.jpg"); //PaintEventArgs e; //teste2.Quantize(bmp); Application.Run(new Quantization()); /* System.Console.WriteLine("Hello, World!"); System.Console.ReadLine();*/ } } 

class级:

 namespace ImageManipulation { public unsafe abstract class Quantizer { ///  /// Construct the quantizer ///  /// If true, the quantization only needs to loop through the source pixels once ///  /// If you construct this class with a true value for singlePass, then the code will, when quantizing your image, /// only call the 'QuantizeImage' function. If two passes are required, the code will call 'InitialQuantizeImage' /// and then 'QuantizeImage'. ///  public Quantizer(bool singlePass) { _singlePass = singlePass; } ///  /// Quantize an image and return the resulting output bitmap ///  /// The image to quantize /// A quantized version of the image public Bitmap Quantize()//Image source) { Image source = Image.FromFile("C:\\Users\\crashboy\\Downloads\\image009.jpg"); // Get the size of the source image int height = source.Height; int width = source.Width; // And construct a rectangle from these dimensions Rectangle bounds = new Rectangle(0, 0, width, height); // First off take a 32bpp copy of the image Bitmap copy = new Bitmap(width, height, PixelFormat.Format32bppArgb); // And construct an 8bpp version Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed); // Now lock the bitmap into memory using (Graphics g = Graphics.FromImage(copy)) { g.PageUnit = GraphicsUnit.Pixel; // Draw the source image onto the copy bitmap, // which will effect a widening as appropriate. g.DrawImage(source, bounds); } // Define a pointer to the bitmap data BitmapData sourceData = null; try { // Get the source image bits and lock into memory sourceData = copy.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); // Call the FirstPass function if not a single pass algorithm. // For something like an octree quantizer, this will run through // all image pixels, build a data structure, and create a palette. if (!_singlePass) FirstPass(sourceData, width, height); // Then set the color palette on the output bitmap. I'm passing in the current palette // as there's no way to construct a new, empty palette. output.Palette = this.GetPalette(output.Palette); // Then call the second pass which actually does the conversion SecondPass(sourceData, output, width, height, bounds); } finally { // Ensure that the bits are unlocked copy.UnlockBits(sourceData); } // Last but not least, return the output bitmap return output; } ///  /// Execute the first pass through the pixels in the image ///  /// The source data /// The width in pixels of the image /// The height in pixels of the image protected virtual void FirstPass(BitmapData sourceData, int width, int height) { // Define the source data pointers. The source row is a byte to // keep addition of the stride value easier (as this is in bytes) byte* pSourceRow = (byte*)sourceData.Scan0.ToPointer(); Int32* pSourcePixel; // Loop through each row for (int row = 0; row < height; row++) { // Set the source pixel to the first pixel in this row pSourcePixel = (Int32*)pSourceRow; // And loop through each column for (int col = 0; col < width; col++, pSourcePixel++) // Now I have the pixel, call the FirstPassQuantize function... InitialQuantizePixel((Color32*)pSourcePixel); // Add the stride to the source row pSourceRow += sourceData.Stride; } } ///  /// Execute a second pass through the bitmap ///  /// The source bitmap, locked into memory /// The output bitmap /// The width in pixels of the image /// The height in pixels of the image /// The bounding rectangle protected virtual void SecondPass(BitmapData sourceData, Bitmap output, int width, int height, Rectangle bounds) { BitmapData outputData = null; try { // Lock the output bitmap into memory outputData = output.LockBits(bounds, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); // Define the source data pointers. The source row is a byte to // keep addition of the stride value easier (as this is in bytes) byte* pSourceRow = (byte*)sourceData.Scan0.ToPointer(); Int32* pSourcePixel = (Int32*)pSourceRow; Int32* pPreviousPixel = pSourcePixel; // Now define the destination data pointers byte* pDestinationRow = (byte*)outputData.Scan0.ToPointer(); byte* pDestinationPixel = pDestinationRow; // And convert the first pixel, so that I have values going into the loop byte pixelValue = QuantizePixel((Color32*)pSourcePixel); // Assign the value of the first pixel *pDestinationPixel = pixelValue; // Loop through each row for (int row = 0; row < height; row++) { // Set the source pixel to the first pixel in this row pSourcePixel = (Int32*)pSourceRow; // And set the destination pixel pointer to the first pixel in the row pDestinationPixel = pDestinationRow; // Loop through each pixel on this scan line for (int col = 0; col < width; col++, pSourcePixel++, pDestinationPixel++) { // Check if this is the same as the last pixel. If so use that value // rather than calculating it again. This is an inexpensive optimisation. if (*pPreviousPixel != *pSourcePixel) { // Quantize the pixel pixelValue = QuantizePixel((Color32*)pSourcePixel); // And setup the previous pointer pPreviousPixel = pSourcePixel; } // And set the pixel in the output *pDestinationPixel = pixelValue; } // Add the stride to the source row pSourceRow += sourceData.Stride; // And to the destination row pDestinationRow += outputData.Stride; } } finally { // Ensure that I unlock the output bits output.UnlockBits(outputData); } } ///  /// Override this to process the pixel in the first pass of the algorithm ///  /// The pixel to quantize ///  /// This function need only be overridden if your quantize algorithm needs two passes, /// such as an Octree quantizer. ///  protected virtual void InitialQuantizePixel(Color32* pixel) { } ///  /// Override this to process the pixel in the second pass of the algorithm ///  /// The pixel to quantize /// The quantized value protected abstract byte QuantizePixel(Color32* pixel); ///  /// Retrieve the palette for the quantized image ///  /// Any old palette, this is overrwritten /// The new color palette protected abstract ColorPalette GetPalette(ColorPalette original); ///  /// Flag used to indicate whether a single pass or two passes are needed for quantization. ///  private bool _singlePass; ///  /// Struct that defines a 32 bpp colour ///  ///  /// This struct is used to read data from a 32 bits per pixel image /// in memory, and is ordered in this manner as this is the way that /// the data is layed out in memory ///  [StructLayout(LayoutKind.Explicit)] public struct Color32 { ///  /// Holds the blue component of the colour ///  [FieldOffset(0)] public byte Blue; ///  /// Holds the green component of the colour ///  [FieldOffset(1)] public byte Green; ///  /// Holds the red component of the colour ///  [FieldOffset(2)] public byte Red; ///  /// Holds the alpha component of the colour ///  [FieldOffset(3)] public byte Alpha; ///  /// Permits the color32 to be treated as an int32 ///  [FieldOffset(0)] public int ARGB; ///  /// Return the color for this Color32 object ///  public Color Color { get { return Color.FromArgb(Alpha, Red, Green, Blue); } } } } } 

编译器警告您, quantit永远不会被初始化,并且始终为null

你可能应该用一个派生自ImageManipulation.Quantizer的类的实例来初始化它(你不能实例化Quantizer本身,因为它是一个抽象类):

 private static Quantizer quantit = new QuantizerImplementation(); 

您永远不会将Quantizer类的实例分配给quantit静态变量,因此它将保持为null引用,并在您尝试使用其中一种方法时生成该exception。 要解决此问题,请在使用之前使用new Quantizer对象初始化该成员。

顺便说一下,我不确定你是否希望该变量是static

编辑

我刚才看到Quantizer是一个抽象类…然后你不能直接实例化它,你首先从它实现abstract方法(即QuantizePixelGetPalette )派生你的特定类或使用另一个现成的类派生来自Quantizer ,然后使用此类的新实例初始化quantit字段。

通过类型名称访问静态成员,即

 Quantization.quantit = {some value}; 

当然,因为它是私有的,你必须从类型内部这样做,在这种情况下你可以使用:

 quantit = {some value}; 

但是,我还要问一下静态是否是一个合适的选项,特别是如果您正在进行任何线程(或Web代码)。 静态经常被过度使用(并且使用不当)。

静态字段只是一个字段,其值由每个人共享。 将其视为全局变量。 问题是你仍然需要至少实例化一次。 通常,这是在与声明相同的时间/地点完成的。

 public static Quantizer quantit = new Quantizer(?); 

我不太了解你想做什么,但我认为你真的不想在这里使用静态字段。 我的猜测是你想根据一些输入参数(singlePass或doublePass)实例化/创建一个新的Quantizer实例。 如果Quantizer类没有状态,则应将其设为单例。 如果您想这样做,我建议您查看dependency injection容器,例如Castle Windsor,它可以更轻松地为您处理。