-1

私はこのメソッドを持っていて、別のメソッドで使用する文字列を返したいと思っていましたが、return ステートメントを for ループに配置すると、メソッドはまだ return を求めています。必要な文字列を返すことができるように、これを適切に構造化するにはどうすればよいですか。

public string ReadDocument(string fileName)
        {
            try
            {
                theImage = codecs.Load(Enhance(fileName), 0, CodecsLoadByteOrder.BgrOrGray, 1, -1); 
                for (int num = 1; num <= theImage.PageCount; num++)
                {
                    BarcodeData dataArray = engine.Reader.ReadBarcode(theImage, LogicalRectangle.Empty, 0, null);
 qrCode = dataArray.Value;

                    if (theImage.Page < theImage.PageCount)
                        theImage.Page++;       
                    return dataArray.Value;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
4

4 に答える 4

4

このコードをコンパイルするには、例外が発生した場合やforループが実行されなかった場合に返す必要がある値を考える必要があります (これtheImage.PageCountは、実行時に厳密に 1 よりも小さい値を返す場合に発生する可能性があります)。たとえば、次のように返すことができますnull

public string ReadDocument(string fileName)
{
    try
    {
        theImage = codecs.Load(Enhance(fileName), 0, CodecsLoadByteOrder.BgrOrGray, 1, -1); 
        for (int num = 1; num <= theImage.PageCount; num++)
        {
            BarcodeData dataArray = engine.Reader.ReadBarcode(theImage, LogicalRectangle.Empty, 0, null);
            qrCode = dataArray.Value;

            if (theImage.Page < theImage.PageCount)
            {
                theImage.Page++;
            }

            return dataArray.Value;
        }

        return null;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
        return null;
    }
}
于 2013-07-02T20:34:08.057 に答える
3

ステートメントから何も返していないため、すべてのコードパスが値を返すわけではないというエラーが発生する場合があります。catch

の値を文字列に保存しdataArray.Value、catch ステートメントの外側で (最後に) この値を返すことができます。

public string ReadDocument(string fileName)
{
    string value = string.Empty;
    try
    {
        theImage = codecs.Load(Enhance(fileName), 0, CodecsLoadByteOrder.BgrOrGray, 1, -1);
        for (int num = 1; num <= theImage.PageCount; num++)
        {
            BarcodeData dataArray = engine.Reader.ReadBarcode(theImage, LogicalRectangle.Empty, 0, null);
            qrCode = dataArray.Value;

            if (theImage.Page < theImage.PageCount)
                theImage.Page++;
            value = dataArray.Value;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
    return value;
}

更新:リストを返したい場合は、戻り値の型をに変更してからList<string>、項目を文字列に追加して、このように返します

List<string> myValues=new List<string>();
for (int num = 1; num <= theImage.PageCount; num++)
        {
            BarcodeData dataArray = engine.Reader.ReadBarcode(theImage, LogicalRectangle.Empty, 0, null);
            qrCode = dataArray.Value;
        if (theImage.Page < theImage.PageCount)
            theImage.Page++;
        myValues.Add(dataArray.Value);
    }

そして戻るmyValues

于 2013-07-02T20:32:38.770 に答える
0

メソッドが事後条件に失敗したため、ここで正しい文字列を返すことができない場合があります。文書を読むように頼んだのに、そうしませんでした。理にかなっている 3 つの潜在的なオプションがあります。

  1. null を返します。次に、呼び出し元で null を処理する必要があります。
  2. 例外を処理できない場合は、例外をキャッチしないでください。呼び出し元に処理させてください。
  3. 例外をキャッチしますが、再スローし、メソッドの失敗した事後条件を反映するために他の型にラップします。

キャッチから再スローしない場合、コンパイラはユーザーが何かを返すことを期待します。つまり、null です。

于 2013-07-02T20:37:29.720 に答える
0

ここで個々のバーコードを読んでいるので、実際に文字列をすぐに連結するよりもIEnumerable<string>and演算子を使用することをお勧めします。yield return

これが私の言いたいことです。ここにいくつかのサンプル「ページ」があります。もちろん、これはプログラム内の実際のデータですが、操作するものを提供します。

    // Example "pages", which would be individual barcodes read using OP's BarcodeReader, but we need some sample data to demonstrate the purpose.
    private string[] _pages = new string[] { "Mung", "Foo", "Bar", "Cookie" };

ReadDocument次に、次の行に沿ってどこかにメソッドを記述します。

    public IEnumerable<string> ReadDocument()
    {
        // Iterate over the pages, and use yield return to add every individual page to the IEnumerable.
        // Using the current Page and the PageLength in your for loop removes the need of having to manually check
        // whether we've reached the end of the pages further down the loop.
        for (int i = 0; i < _pages.Length; i++)
        {
            // BarcodeData dataArray = engine.Reader.ReadBarcode(theImage, LogicalRectangle.Empty, 0, null);
            // qrCode = dataArray.Value;

            yield return _pages[i]; // dataArray.Value in your own code.
        }
    }

これにより、読んだばかりのすべてのページがナイスIEnumerableに表示され、foreach後で個々のページを取得することができます。

ReadDocument().Aggregate(string.Empty, (current, s) => current + s);

読み取ったすべてのページを文字列に直接マージするよりもこのアプローチの利点は、未加工の形式ですべてのデータにアクセスでき、後から必要なく自由に操作できることSplit()です。

コードはもはやあなた自身のコードではありませんが、この特定の問題にどのようにアプローチすることをお勧めするかについて明確なアイデアを提供するはずです。それを適応させて、あまり問題なく独自のコードで使用できるはずです。

于 2013-07-02T21:47:07.707 に答える