C# 为什么在尝试在try块的finally station中处理资源时会出现此错误?

C# 为什么在尝试在try块的finally station中处理资源时会出现此错误?,c#,.net,C#,.net,我在处理资源时遇到一些问题 我有以下代码: class ChartHelper { //public static System.Drawing.Image GetPdfChart(int percentage) public static System.Drawing.Bitmap GetPdfChart(int percentage) { if (percentage == 0)

我在处理资源时遇到一些问题

我有以下代码:

    class ChartHelper
    {

        //public static System.Drawing.Image GetPdfChart(int percentage)
        public static System.Drawing.Bitmap GetPdfChart(int percentage)
        {
            if (percentage == 0)
            {
                return null;
            }

            int WIDTH = 130;
            int HEIGHT = 10;


            //using (Bitmap bitmap = new Bitmap(WIDTH, HEIGHT))
            //{
            Bitmap bitmap;
            try {
                bitmap = new Bitmap(WIDTH, HEIGHT);
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, WIDTH, HEIGHT), Color.LightGreen, Color.Red, LinearGradientMode.Horizontal))
                    {
                        graphics.FillRectangle(brush, new Rectangle(0, 0, WIDTH, HEIGHT));

                        using (Bitmap target = new Bitmap(WIDTH * percentage / 100, HEIGHT))
                        {
                            Rectangle cropped = new Rectangle(0, 0, WIDTH, HEIGHT);

                            using (Graphics g = Graphics.FromImage(target))
                            {
                                g.DrawImage(bitmap, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped, GraphicsUnit.Pixel);
                                //g.Save();
                                //String filename = Path.GetTempFileName() + ".png";
                                //target.Save(filename);
                                //return filename;

                                return bitmap;
                            }
                        }
                    }
                }
            }
            finally
            {
               bitmap.Dispose(); 
            }
        }

    }
正如您在开始时看到的,我创建了一个位图对象,方法如下:

bitmap = new Bitmap(WIDTH, HEIGHT);
进入尝试

在块的末尾,我有一个最后的,其中我尝试处理资源:

finally
{
    bitmap.Dispose(); 
}
但在这里,它给了我以下错误消息:

错误2使用未分配的局部变量“位图”

为什么??我能做些什么来解决它?(我不想使用using语句)

Tnx

为什么?

因为根据语言规范的规则,
bitmap
没有明确指定。想象一下,如果
位图
构造函数抛出异常。你会怎么处理

我能做些什么来解决它?(我不想使用using语句)

你可以使用:

但是,我强烈建议您对此使用
using
语句。这就是它的设计目的,也是惯用的方法

作为一个稍微独立的问题,您将从块的中间返回位图,但您正在处理它。是否确实要返回对已处理位图的引用?你希望打电话的人能用它做什么?您可能需要考虑仅在故障时处理位图。e、 g

Bitmap bitmap = null;
bool success = false;
try
{
    bitmap = ...;
    // Code using bitmap
    ...
    success = true;
    return bitmap;
}
finally
{
    if (bitmap != null && !success)
    {
        bitmap.Dispose();
    }
}

在这一点上,您当然有一个很好的理由不使用
using
语句…

因为您没有为位图分配任何内容,所以无法处理它! 即使指定“null”也可以解决这个问题。 虽然它不像你想要的那么“干净”。 在声明中指定null,然后在处理它之前检查它是否为null,这样会更好。
小心!如果要返回对象。

位图.Dispose
调用开始,
位图
可能没有值(如果
新建位图
引发异常)

因为在正常情况下,您将位图返回给调用者,我可能会这样做:

Bitmap bitmap = null;
…这样
bitmap
肯定有一个值,然后在
finally
子句中添加一个
null
检查:

finally
{
    if (bitmap != null) {
        bitmap.Dispose();
    }
}
…并在返回时四处走动:

Bitmap rv = bitmap;
bitmap = null;
return rv;

您不应该在位图上使用Dispose,因为它是由函数返回的:

    public static System.Drawing.Bitmap GetPdfChart(int percentage)
    {
        if (percentage == 0) return null;

        int WIDTH = 130;
        int HEIGHT = 10;

        Bitmap bitmap = new Bitmap(WIDTH, HEIGHT);
        using (Graphics graphics = Graphics.FromImage(bitmap))
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, WIDTH, HEIGHT), Color.LightGreen, Color.Red, LinearGradientMode.Horizontal))
            {
                graphics.FillRectangle(brush, new Rectangle(0, 0, WIDTH, HEIGHT));

                using (Bitmap target = new Bitmap(WIDTH * percentage / 100, HEIGHT))
                {
                    Rectangle cropped = new Rectangle(0, 0, WIDTH, HEIGHT);

                    using (Graphics graphicsTarget = Graphics.FromImage(target))
                    {
                        graphicsTarget .DrawImage(bitmap, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped, GraphicsUnit.Pixel);

                        return bitmap; // IT IS RETURNED HERE, SO DO NOT DISPOSE
                        // should'nt this be target anyway?
                    }
                }
            }
        }   
    }
使用如下函数确保正确执行处置:

using(var bmp = GetPdfChart(somePercentage))
{
     // code goes here.
}
但是,如果您确实需要确保在出现错误时正确处理位图

public static System.Drawing.Bitmap GetPdfChart(int percentage)
{
    if (percentage == 0) return null;

    int WIDTH = 130;
    int HEIGHT = 10;

    Bitmap bitmap = null;
    bool functionReturned = false;
    try
    {
        bitmap = new Bitmap(WIDTH, HEIGHT);

        using (Graphics graphics = Graphics.FromImage(bitmap))
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, WIDTH, HEIGHT), Color.LightGreen, Color.Red, LinearGradientMode.Horizontal))
            {
                graphics.FillRectangle(brush, new Rectangle(0, 0, WIDTH, HEIGHT));

                using (Bitmap target = new Bitmap(WIDTH * percentage / 100, HEIGHT))
                {
                    Rectangle cropped = new Rectangle(0, 0, WIDTH, HEIGHT);

                    using (Graphics graphicsTarget = Graphics.FromImage(target))
                    {
                        graphicsTarget .DrawImage(bitmap, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped, GraphicsUnit.Pixel);
                        functionReturned = true;

                        return bitmap; // IT IS RETURNED HERE, SO DO NOT DISPOSE
                        // should'nt this be target anyway?
                    }                   
                }
            }
        } 
    }
    finally
    {
        if(!functionReturned && bitmap != null) bitmap.Dispose();
    }
}

为什么不想使用
using
语句?这就是它的设计目的。你根本不应该处理
位图
!您正在将它返回给调用者,调用者有责任处理它。除了OP正在从函数返回位图,因此根本不应该处理它。@t.J.Crowder:是,我刚刚注意到了这一点,并在答案的末尾添加了一些内容。如果新位图出现问题,可能希望在错误处理中进行处理。如果以后发生异常,上述操作将不会调用
Dispose
public static System.Drawing.Bitmap GetPdfChart(int percentage)
{
    if (percentage == 0) return null;

    int WIDTH = 130;
    int HEIGHT = 10;

    Bitmap bitmap = null;
    bool functionReturned = false;
    try
    {
        bitmap = new Bitmap(WIDTH, HEIGHT);

        using (Graphics graphics = Graphics.FromImage(bitmap))
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, WIDTH, HEIGHT), Color.LightGreen, Color.Red, LinearGradientMode.Horizontal))
            {
                graphics.FillRectangle(brush, new Rectangle(0, 0, WIDTH, HEIGHT));

                using (Bitmap target = new Bitmap(WIDTH * percentage / 100, HEIGHT))
                {
                    Rectangle cropped = new Rectangle(0, 0, WIDTH, HEIGHT);

                    using (Graphics graphicsTarget = Graphics.FromImage(target))
                    {
                        graphicsTarget .DrawImage(bitmap, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped, GraphicsUnit.Pixel);
                        functionReturned = true;

                        return bitmap; // IT IS RETURNED HERE, SO DO NOT DISPOSE
                        // should'nt this be target anyway?
                    }                   
                }
            }
        } 
    }
    finally
    {
        if(!functionReturned && bitmap != null) bitmap.Dispose();
    }
}