電子書籍の厳選無料作品が豊富!

 こんにちは。c#初心者です。

 よくインデックスなどで引数が負数でないかのチェックを行いますが、その代わりに引数を符号なし整数、例えば「uint」にしてしまうというのはどうなのでしょうか?

 初心者から見た長所は負数のチェックを行うより「int」から「uint」へのキャストのほうがやや高速(とはいっても全体的なパフォーマンスへの影響は薄い)。利用側が、負数がダメだと”やや”わかりやすくなる。
 短所は「checked」がないと負数でオーバーフローを起こしても放置されること。(uint)が至る所に発生してむしろ可読性が下がるかもしれないことと、面倒になること(これは大きいかもしれない)。
(負数のチェックだけでなく上限のチェックが必要な場合は「int」、「uint」かかわらずチェックするので「uint」だからといって超えすぎる心配はなく、その場合、オーバーフローも間接的に例外として検出される)

 という感じなのですが、なにせ初心者なわけで、皆さんのご意見をうかがわせてもらえませんか?

A 回答 (4件)

> こういうのはどうなのでしょう?



uintとintの比較は出来ないので両方ともuintにキャストしなきゃなりませんが、そこまでして負数チェックをしたくないんでしょうか?
つーかC#使ってる時点でこんな細かすぎる速度最適化は考えない方がいいと思いますけど。
    • good
    • 0
この回答へのお礼

 回答ありがとうございます。

> そこまでして負数チェックをしたくないんでしょうか?
 前記の通り、飽くまで気になっただけです。

> uintとintの比較は出来ないので
 ということは「if ( count <= (uint)index )」(countはint型)でコンパイルエラーが出なかったので暗黙の型変換がかかっているということでしょうか? 僕の記憶では暗黙の型変換はできかかったと思うのですが。

> C#使ってる時点でこんな細かすぎる速度最適化は考えない方がいい
 まあ、計算量を減らすことが先決ですよね。

お礼日時:2012/05/29 13:59

> 短所は「checked」がないと負数でオーバーフローを起こしても放置されること。

(uint)が至る所に発生してむしろ可読性が下がるかもしれないことと、面倒になること(これは大きいかもしれない)。

コレに関しては、更に致命的な弊害である「型エラーが出ているところを何も考えずにキャストする習慣を生みかねない」ということを指摘しておきましょう。まぁC#だと全く無関係な型の間でのキャストは不能ですが。
#2でも言われてますが、大抵のインデクサは引数がintなのだから同様にしておくべきでしょうね。
    • good
    • 0
この回答へのお礼

 回答ありがとうございます。

> #2でも言われてますが、
> 大抵のインデクサは引数がintなのだから同様にしておくべきでしょうね。

 これについても投稿した後になって思いついたのですが、こういうのはどうなのでしょう?
(本当に殆ど速度は変わらなかったので何のこだわりもないのですが気になったので一応)

 以下「count」を「private」な負数でない「int」型整数とする。

 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
public class List<T> : IList<T>
{
  public T this[int index]
  {
  get
    {
      if ( count <= (uint)index )
        throw new ArgumentOutOfRangeException("index");
      ……//処理
    }
  set
    {
      if ( count <= (uint)index )
        throw new ArgumentOutOfRangeException("index");
      ……//処理
    }
}
_______________________/

 見かけ上の引数の型は保たれるので、外部から使用する分に関しては問題ないかと思うのですがどうなのでしょうか? 時間がありましたらどなたでも良いのでご意見ください。

お礼日時:2012/05/29 09:24

> に置き換えることは可能か? ということです。



可能かと聞かれれば、可能ですと答えます

が、たぶん私はやりません
統一性にかけるからです

IList<T> にも、IndexOfメソッドはありますよね
発見できない場合どうするのでしょうか?

会社の同僚が VBで作成したクラスに、
Count プロパティがあり使用してみたら
Count -1 の値が返されていて( For i=1 To xxx.Count とかしたかったらしい)
トラブルの原因になった経験がある私としては、
共通事項として浸透しているものは変えない方が
不具合の軽減になると思いますよ
    • good
    • 0
この回答へのお礼

 回答ありがとうございます。

 Countが-1を返すのは初耳です。仕様によってはそういうこともありうるのですね。覚えておきます。

お礼日時:2012/05/29 09:09

普通インデックスが負数になるという事は、選ばれていないという合図として


処理しませんか?

たとえば、
IndexOf メソッドは配列を検索し、発見できればそのインデックス番号を、
発見できなければ -1 を返します。

コンボボックスのリスト等は、選択された行があれば、そのインデックス番号、
選択されていなければ -1 を返します

発見できなかった/選択されなかった場合の処理を行う事の方が重要だと思います
エラーな物を強制的に uintにして、その後の動きが意味不明になる方法を取る
事の方がおかしいと思います

この回答への補足

> 普通インデックスが負数になるという事は、
> 選ばれていないという合図として
> 処理しませんか?

 無論、いくつかの戻り値や、比較的少ないですが引数では「-1」などを整数の数少ない特別な状態の表現方法の1つとしてありがたく使わせてもらっています。


> エラーな物を強制的に uintにして……(以下略)

 国語力が多分平均以下のこちらにも落ち度があったと思いますが、質問の意図を汲んでもらえなかったので補足です。
 僕が言葉を連ねてもまた意図が伝わらなさそうなので具体例を挙げます。

 以下、「count」を静的でない「int」型のフィールド変数とします。

 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
public class List<T> : IList<T>
{
  public T this[int index]
  {
  get
    {
      if ( index < 0 || count <= index )
        throw new ArgumentOutOfRangeException("index");
      ……//処理
    }
  set
    {
      if ( index < 0 || count <= index )
        throw new ArgumentOutOfRangeException("index");
      ……//処理
    }
}
_______________________/



 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
public class List<T> : IList<T>
{
  public T this[uint index]
  {
  get
    {
      if ( count <= index )
        throw new ArgumentOutOfRangeException("index");
      ……//処理
    }
  set
    {
      if ( count <= index )
        throw new ArgumentOutOfRangeException("index");
      ……//処理
    }
}
_______________________/

 に置き換えることは可能か? ということです。
 上記は飽くまで例えなので、「この場合は無理」、「この場合はOK」などありましたらご指摘ください。

補足日時:2012/05/28 18:52
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!