1

メソッド/関数の呼び出し元から「ArgumentOutOfRangeException」を取得する方法があるかどうかを知りたいです。

これを何日も探していましたが、運がありません...まれにあるか、検索パラメーターの選択が悪い...

例:

class Main
{
    struct XYZ
    {
        public int X, Y, Z;
        public XYZ(int x, int y, int z)
        {
            X = x;
            Y = y;
            Z = z;
        }
    }
    class ArrayE<T>
    {
        public T[, ,] data;

        public ArrayE(XYZ xyz)
        {
            data = new T[xyz.X, xyz.Y, xyz.Z];
        }
        public T this[XYZ xyz]
        {
            get
            {
                if (OutOfBounds(xyz))
                {
                    throw new ArgumentOutOfRangeException(); // Error shows here in debug
                }
                else
                {
                    return data[xyz.X, xyz.Y, xyz.Z];
                }
            }
            set
            {
                if (OutOfBounds(xyz))
                {
                    throw new ArgumentOutOfRangeException(); // Error shows here in debug
                }
                else
                { 
                    data[xyz.X, xyz.Y, xyz.Z] = value; 
                }
            }
        }

        bool OutOfBounds(XYZ xyz)
        {
            return xyz.X < 0 | xyz.Y < 0 | xyz.Z < 0 |
                       xyz.X >= data.GetLength(0) |
                       xyz.Y >= data.GetLength(1) |
                       xyz.Z >= data.GetLength(2);
        }
    }

    ArrayE<int> Data;
    public void Test()
    {
        XYZ xyz = new XYZ(10, 10, 10);
        Data = new ArrayE<int>(xyz);

        xyz = new XYZ(1,0,2);
        Data[xyz] = 2;


        xyz = new XYZ(1, -1, 2);
        Data[xyz] = 4; // I would like the debugger to stop here
        //As if I did this:
        Data[xyz.X,xyz.Y,xyz.Z] = 4 // The debugger would then stop at this line

        //Example of what I want
        int[] array = new int[10];
        array[2] = 1;
        array[-1] = 3; // This is the behavior I would like to happen when out of bounds, The error shows here.
    }
}

編集:より具体的に:
デバッグを開始するときに、デバッガーを「Data [xyz] = 4;」の行で停止させたい ここで、xyz は無効なインデックスであるため、Data[xyz] get set 関数内からではなく、どこから呼び出されたのかがわかります。

通常の int[] が無効なインデックス (-1 など) を取得する場合、デバッガーはその行で停止し、配列がアクセスされる前の行を調べることができるため、インデックスが変更された理由を見つけることができます。それが何であるかです。現在のセットアップでは、ArrayE[xyz] で xyz の無効なインデックスが使用されると、デバッガーが get セット内で停止し、xyz が配列の境界外にある理由を追跡して把握することができなくなります...

私が何を求めているのか、それがより明確になることを願っています。
try catch を使用することもできますが、他に方法はありませんか? プログラムが非常に大きいため、try catch を実行すると、すぐにコードが読めなくなり、管理できなくなります...

では、可能であればどのようにすればよいのでしょうか。

Visual C# 2010 Express を使用しています

4

1 に答える 1

0

あなたが投稿したこのコードを実行するだけで、あなたが望むことをしているように見えます。発信者がそれをキャッチして処理する例を以下に示します。テスト関数でこれらを処理したい場合は、try キャッチを下に移動します。

public class Program
{
    public static void Main(string[] args)
    {
        try
        {
            Main m = new Main();
            m.Test();
        }
        catch (Exception e)
        {
            Console.Write("Uh oh :O " + e.StackTrace);
        }
    }
}

編集:さて、これを見た後、私はあなたが求めていることを行う方法を思いつきました. DebugerHidden 属性を設定する必要があります。例:

        public T this[XYZ xyz]
        {
            //add attribute here to say this function is 'ignored'
            [DebuggerHidden]
            get
            {
                if (OutOfBounds(xyz))
                {
                    throw new ArgumentOutOfRangeException(); // Error shows here in debug
                }
                else
                {
                    return data[xyz.X, xyz.Y, xyz.Z];
                }
            }
            //add attribute here to say this function is 'ignored'
            [DebuggerHidden]
            set
            {
                if (OutOfBounds(xyz))
                {
                    throw new ArgumentOutOfRangeException(); // Error shows here in debug
                }
                else
                {
                    data[xyz.X, xyz.Y, xyz.Z] = value;
                }
            }
        }
于 2013-02-24T03:15:30.430 に答える