c# 例外が重複する場合
- c#初心者のため、例外の重複について質問です。引数の前提条件や例外のチェックについて知りたいです。
- c#初心者の質問:例外が重複した場合に、引数の前提条件や例外のチェックは必要ですか?詳しい方の意見を聞きたいです。
- c#初心者の質問:例外の重複について教えてください。引数の前提条件や例外のチェックについてよく理解していません。
- ベストアンサー
c# 例外が重複する場合
こんにちは。c#初心者です。 今回は例外に関する質問です。 ----------------------------------------------------- list1, list2を「System.Collections.Generic.List<int>」とします。 int GetValue(int index1, int index2) { //*1 //とりあえず、何らかの計算を行う(この場合は掛け算) return list1[index2] * list2[index2]; } ----------------------------------------------------- 上記の場合、普通だったら引数の範囲のチェックが必要になると思うのですが、たまたまList<T>の既定の「0~Count - 1」の範囲とまったく同じだった場合、 一般化していえば、現在のメソッド(、プロパティ、インデクサ、コンストラクタ)の引数の前提条件と、その中で呼び出されるメソッド(、プロパティ、インデクサ、コンストラクタ)の前提条件が等しく、スローされる例外も等しい場合、*1に if ( index1 < 0 || index1 <= list1.Count ) …… if ( index2 < 0 …… は必要でしょうか? それとも呼び出される側に任せて例外のチェックを行わなくても良いのでしょうか? チェックなどは重複しないほうがよいとは思うのですが、まだ細かいところがわかりません。どなたか詳しい方がいらっしゃいましたらご意見を伺わせてください。
- koumei000
- お礼率84% (147/173)
- C・C++・C#
- 回答数1
- ありがとう数1
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
GetValueがJavaの標準ライブラリのようにどのような状況で使用されるかまったくわからない場合は、チェックすべきです。 アボートしてしまいますからね。 そうではなくて呼び出し側の仕様も明確で呼び出し側でチェックされることが明白な場合はチェックは不要です。 回答が当たり前過ぎましたか? メソッドの仕様ひとつ決めるのにも、必ずメリット・デメリットがあります。 確かにチェックした方が仕様的には、完璧ですが、実際の開発現場では、時間的に余裕がない場合もありますし、 二重にチェックする必要はありません。
関連するQ&A
- c# 例外の重複・改
こんにちは。なんとなく質問が上手でないc#初心者です。 この前になんと言うか、聞き方が悪かったのか、理解力が足りなかったのか、しっくりこない回答しかもらえなかったのですが、GoF本を読んだら新しい見方を学んだので再挑戦(質問)します。 単刀直入にいうと、Decoratorパターンや, Proxyパターンで「装飾、フックを行うメソッド(MethodA)」はその「装飾、フックされるメソッド(MethodB)」で行われているものと“同じ”例外のチェックを行うべきですか? という質問です。 void MethodA(int val) { if ( valに関する条件A ) throw new ArgumentOutOfRangeException("val"); MethodB(int val); …… // 処理 } ---------------------------- void MethodB(int val) { if ( valに関する条件A ) throw new ArgumentOutOfRangeException("val"); …… // 処理 } 言い換えると、まったく同じ例外のチェックを重複させる意味はあるのか? という意味です(もしかしたら僕以外の人には当たり前すぎて話にならないかも知れませんが)。以前はJavaの標準ライブラリではまずいかもしれないと言われました(何のことやらサッパリです)。 以前と質問内容が変わっていない気もしますが、とりあえず 1、意味の有無 2、 1が有の場合、動作の変化、バグ等 を今回の質問内容とします。 どなたかご存知の方、または「こう思う」という方がいらっしゃいましたらご意見を伺わせてください。
- ベストアンサー
- C・C++・C#
- C#
C#の質問です。 『クラスIntArrayを作成し、作成したクラスが正常に動作するか検証するためのクラスを作成してください。』 というプログラムを組んでおり、クラスIntArrayとその動作を検証するクラスを作成したのですが、クラスIntArrayについて「問題文で指定された通りに作成されていません。」という指摘を受けました。 何度も見直したのですが、どの部分が指定された通りになっていないのか、自分では見つけることが出来ませんでした; 私が作成したクラスIntArrayとその仕様については、下記のとおりです。 お分かりになる方がいらっしゃいましたら、ご助言をお願いいたします。 【クラスIntArray 仕様】 <インスタンス変数> int型の配列data <コンストラクタ> 以下の3種類を用意します。 ・int型の配列を受け取り、そのコピーを内部的に保持します。 ・第1引数で指定された要素数を持つ配列を確保し、全ての要素に初期値として第2引数で指定された値をセットします。 ・第1引数で指定された要素数を持つ配列を確保し、全ての要素に初期値としてゼロをセットします。 <メソッド> ・Sort 内部的に保持している配列を、引数の値がtrueであれば昇順、falseであれば降順にソートする ・Length IntArrayが保持している配列の要素数を取得する ・GetElement 引数に指定された要素番号の値を取得する ・SetElement 第1引数に指定された要素番号に第2引数で指定された値を格納する ・GetArray IntArrayが保持している配列のコピーを取得する 【作成したクラスIntArray】 using System; private int[] data; public IntArray(int[] array) { this.data = new int[array.Length]; array.CopyTo(this.data, 0); for (int index = 0; index < this.data.Length; index++) { // 先頭の要素以外を出力する場合 if (index > 0) { Console.Write(", "); } Console.Write(this.data[index]); } Console.WriteLine(); } public IntArray(int args1, int args2) { int[] myarray = new int[args1]; for (int index = 0; index < args1; index++) { myarray[index] = args2; } for (int index = 0; index < myarray.Length; index++) { // 先頭の要素以外を出力する場合 if (index > 0) { Console.Write(", "); } Console.Write(myarray[index]); } Console.WriteLine(); } public IntArray(int args) { int[] myarray = new int[args]; for (int index = 0; index < args; index++) { myarray[index] = 0; } for (int index = 0; index < myarray.Length; index++) { // 先頭の要素以外を出力する場合 if (index > 0) { Console.Write(", "); } Console.Write(myarray[index]); } Console.WriteLine(); } public void Sort(bool flg) { Array.Sort(this.data); //昇順にソート if (!flg) //降順にソート { Array.Reverse(this.data); } for (int index = 0; index < this.data.Length; index++) { // 先頭の要素以外を出力する場合 if (index > 0) { Console.Write(", "); } Console.Write(this.data[index]); } Console.WriteLine(); } public int Length() { return this.data.Length; } public int GetElement(int args) { int getvalue = this.data[args]; return getvalue; } public void SetElement(int args1, int args2) { this.data[args1] = args2; } public void GetArray() { for (int index = 0; index < this.data.Length; index++) { // 先頭の要素以外を出力する場合 if (index > 0) { Console.Write(", "); } Console.Write(this.data[index]); } Console.WriteLine(); } }
- ベストアンサー
- C・C++・C#
- C# 例外が発生しないことの保障
Javaと比較して書きます。 Javaで記述した場合: public class JavaClass { public static SampleClass s = new SampleClass(); } C#で記述した場合: public class CSharpClass { public static SampleClass s = new SampleClass(); } JavaでもC#でも、同じコードを記述しているように見えますが、Javaではnew SampleClass()コンストラクタで例外が発生しない事が分かっているのに対して、C#の場合では例外が発生しないとは言い切れません。 これは、Javaでは、例外をスローする可能性のあるメソッド宣言では、その全てについてthrows宣言をしなければいけないのに対して、C#にはこの制約が存在しないことが原因です。 これについて何が困るかといいますと、C#で、static宣言な変数や静的コンストラクタで安易にメソッド呼び出し等を行うと、キャッチできなくなってしまいます。 public class Exceptionner { public Exceptionner() { throw new ApplicationException("Exceptionnerクラスの例外"); } } public class SampleClass { public static Exceptionner e = new Exceptionner(); // ここで例外が発生するが、キャッチできない。 } public class MyEntryPoint { public static void Main() { try { SampleClass s = new SampleClass(); } catch (Exception e) { // System.ApplicationExceptionでなくSystem.TypeInitializationExceptionとなる。 // つまり、元の例外の情報は失われている Console.WriteLine(e.GetType()); } } } これを現在漠然と問題視していますが、何かよい解決策はありませんでしょうか。 望んでいる解決策: ・C#でもメソッドが例外を返さないという保障がソースレベルでメソッドやコンストラクタに宣言可能? ・C#では例外をちゃんとキャッチしなくてもスマートに記述することが可能? ・問題視する必要がない?(whyも含めて)
- ベストアンサー
- C・C++・C#
- PHPの関数をC#で再現したい
このジャンルでお願いします。 C# 2010 version 4.0を使用しています。 PHPという言語で isset( mixed $var [, mixed $... ] ) ・・・ 変数がセットされており、それが NULL でないことを調べる と array_key_exists ( mixed $key , array $search ) ・・・ 指定した key が配列に設定されている場合、 TRUE を返す という2つの関数がありますが、それぞれC#で同じような機能を再現しようとした場合に、 どのような記述やメソッドを使えば良いのでしょうか? 自分としては、C#のListを使って試しているのですが、 Listのメソッドにそれらしきものがなくて、 Countプロパティで指定したインデックス以下だったらと存在しない という無理なやり方しか思いきません・・・ if (list.Count <= indexKey) { /*存在しない*/ } 上の2つの機能をなんとかして再現することはできないでしょうか?
- 締切済み
- その他(プログラミング・開発)
- c# 行と列 どっちが先?
こんにちは。c#初心者です。 インデクサやメソッドなどで行を表す引数と、列を表す引数のどちらを先に持って来ればよいか分からず質問させてもらいました。 具体的には int this[int row, int column] { get; set; } なのか、 int this[int column, int row] { get; set: } なのかで迷っています。最初は前者で作るつもりだったのですが、「TableLayoutControlCollection」によると、 public void Add(Control control, int column, int row) のようになっており、後者の順だったので分からなくなってしまいました。 どなたかご存知の方がいらっしゃいましたら教えていただけませんか?
- ベストアンサー
- C・C++・C#
- C++変数宣言時のコンストラクタについて
Java開発をこれまでやってきたのですが、 C++を学ぼうとしています。 C++では下記のように宣言した場合hogeは インスタンスになり、Hogeクラスのコンストラクタが呼ばれるようなのですが、 Hoge hoge; Hogeクラスのコンストラクタが下記のような引数を持つものしか定義されていなかった場合は どの様な振る舞いをするのでしょうか? Hoge(int num); Javaでは引数の有るコンストラクタしか宣言しなかった場合はデフォルトコンストラクタは 作られなかったと思うのですが、c++では引数のないデフォルトコンストラクタができてるのでしょうか? また、デフォルトコンストラクタが出来ていなかった場合、 Hoge hoge; というようにプリミティブ型のような変数宣言の仕方で引数有りのコンストラクタを呼ぶことは出来るのでしょうか?
- ベストアンサー
- C・C++・C#
- Java初心者です、エラーの意味が理解できません
今晩は。Java初心者です、宜しくお願いします。 下のようなコードを書きましたが、 「コンストラクタ'sub(int)'は未定義です」、 「/型subのメソッド'disp(int)'は引数()に適用出来ません」というエラーが出ます。 エラーの意味が理解できません。 1.メソッドのみを持ったクラスSubに値をこのような渡し方は不可なのでしょうか。 2.Subには自動的にコンストラクタが生成されないのでしょうか。 されないとすれば、どの部分の書き方が悪いのでしょうか。 3.「型subのメソッド'disp(int)'への引数の渡し方」は、文法的にまずいということでしょうか。 それとも全てコンストラクタの生成が原因なのでしょうか。 ========================================================================= class Sub { void disp(int a) { System.out.println("a = " + a ); } } public class クラス { public static void main(String[] args) { Sub s = new Sub(10); //コンストラクタ'sub(int)'は未定義です s.disp(); //型subのメソッド'disp(int)'は引数()に適用出来ません } }
- ベストアンサー
- Java
- objective-cでのリバーシプログラミング
xcodeのobjective-cでのリバーシのプログラムを書いていますが、コマをひっくり返すための仕組みがよくわかりません。 C言語はわからないのですが、ソースをみて色々とやっているんですがうまくいきません。 まず一列で考えてみています。 int board[] = {-1,0,0,2,2,2,1,-1}; を用意し、黒を1、白を2、コマ無しを0、番外を-1と考え、 3番目に黒を置いた場合に、白のコマ数を数える様にメソッドを作ろうと考えています。 要するに置いたコマの横に相手のコマがあって、さらにその先に自分のコマがある場合を想定し、 その場合の相手のコマ数を数えるメソッドを作りたいと考えています。 int countをグローバルにおいて、 - (void)countKoma { count = 0; for (int i = 0; board[2 + i] == 2; i++) { if(board[2+ i] == player) { count++; } } と言うメソッドを作って viewDidLoadで呼び出しているんですが、 for文が動いていないようです。 間違っている部分、 もしくはコマをひっくり返すいい方法、アドバイス等があれば教えて下さい。 よろしくお願いします。
- ベストアンサー
- その他(プログラミング・開発)
- c# チェックか符号なしか
こんにちは。c#初心者です。 よくインデックスなどで引数が負数でないかのチェックを行いますが、その代わりに引数を符号なし整数、例えば「uint」にしてしまうというのはどうなのでしょうか? 初心者から見た長所は負数のチェックを行うより「int」から「uint」へのキャストのほうがやや高速(とはいっても全体的なパフォーマンスへの影響は薄い)。利用側が、負数がダメだと”やや”わかりやすくなる。 短所は「checked」がないと負数でオーバーフローを起こしても放置されること。(uint)が至る所に発生してむしろ可読性が下がるかもしれないことと、面倒になること(これは大きいかもしれない)。 (負数のチェックだけでなく上限のチェックが必要な場合は「int」、「uint」かかわらずチェックするので「uint」だからといって超えすぎる心配はなく、その場合、オーバーフローも間接的に例外として検出される) という感じなのですが、なにせ初心者なわけで、皆さんのご意見をうかがわせてもらえませんか?
- ベストアンサー
- C・C++・C#
- Java クラスを使ったソート
Javaで隣接交換法を用いて配列dataを昇順に並び替え、出力するプログラムを作成する。 ただし、ループ処理には、int型の変数は使わず、以下のCounterクラスを使用する。 という課題が出て、とり組んでみたのですが所々よく分からないので、お力添えしていただければと思います。 課題には下記のような条件が書いてありました。 配列data={54,76,32,89,45,11,8,54,29,67}; [クラス] Counter [インスタンス変数] int型の値を保持するcount [コンストラクタ] 引数で渡された値を初期値としてインスタンス変数に設定する。 引数を省略された場合、ゼロを設定する。 [メソッド] increment 値に1加算する decrement 値に1減算する compareTo 以下の処理を行う Counterの保持している値が引数に指定された値と 等しい場合、値0を返す。 Counterの保持している値が引数に指定された値より 小さい場合、0より小さい値を返す。 Counterの保持している値が引数に指定された値より 大きい場合、0より大きい値を返す。 get Counterの保持している値を添え字として、 引数で渡された配列の要素を取得します。 set Counterの保持している値を添え字として、 第1引数で渡された配列に第2引数で渡された値を設定します。 以下組んだものです。 ---- class Counter { int count = 0; Counter(int count) { this.count = count; } Counter() { this.count = 0; } public int get(int[] data) { return this.count; } public void set(int[] data, int count) { this.count = count; } public void increment() { this.count = count + 1; } public void decrement() { this.count = count - 1; } public int compareTo() { return count; } } public class Lesson09 { public static void main(String args[]) { Counter counter = new Counter(0); int[] data = {54, 76, 32, 89, 45, 11, 8, 54, 67}; counter.get(data); counter.set(data, 0); } } ---- とりあえず、compareToとsetとgetの部分をどう記述していいのかがよく分かりません。 よろしくお願いします。
- ベストアンサー
- Java
お礼
回答ありがとうございます。 えーっと、Javaはまだ扱ったことがないので、インタープリタとか、c++を基にしてできたことと、c#の基になったこと以外はさっぱりなのですが、Javaでは  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\ void SampleMethod1(int value) { if ( value < 0 ) throw new ArgumentOutOfRangeException("value"); } _____________________/ と  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\ void SampleMethod2(int value) { //*1 SampleMethod1(value); } _____________________/ があったとしたら、*1に  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\ if ( value < 0 ) throw new ArgumentOutOfRangeException("value"); _____________________/ があったほうが良いということですか? 後々にJavaもやる予定なので2重にチェックを入れるのと入れないのとでの挙動の違いも聞きたいのですがよろしいですか?