VB のたまご

作成日: 2015/12/03, 更新日: 2015/12/03


ArgumentException について

概要

  •  ArgumentException は、メソッドに渡した引数が不正な値の場合に、発生する例外エラーです。 渡した引数の値が、そのメソッドの目的を達成できるような形式になっているかどうか、 例えば、引数がフォルダパスやファイルパスであれば、実際に存在しているかどうか、という視点から見ると解決の糸口につながります。


スポンサーリンク


事例と対処方法

  •  以下のサンプルは、意図的に例外エラーを発生させるコードです。 実際の業務プログラムでは、このような簡単なコードではないと思いますが、例外発生させている、直接的な原因となる部分として参考になるはずです。 また、本例外エラーが発生してしまう原因となった、根本的な原因となる別の例外エラーが、さらに奥深くにいる場合があります。 (本例外エラーは間接的に影響を受けて発生してしまったもので、本当の原因となる例外エラーを食い止めることで、本例外エラーも直る場合があります。)

  •  このような組み合わせのパターンは、本例外エラーに限らず、他の例外エラー全般にも言えることですが、そんなに頻繁に出くわすものではないと思いますので、 そういう場合もあるということだけ、覚えておいていただけると解決しやすくなるのではと思います。

  •  また、記載の対処方法は、あくまでも一例です。 他の対処方法の方が、その業務プログラムにとってベストプラクティスとなる場合もありますので、検討材料の1つという程度に確認していただければと思います。

  • スポンサーリンク



  • Hashtable
  • Dim ht As New Hashtable
    ht.Add("a", 100)
    ht.Add("a", 200)
    
    ' 例外エラー
    System.ArgumentException: 項目は既に追加されています。辞書のキー: 'a'  追加されるキー:'a'
       場所 System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
       場所 System.Collections.Hashtable.Add(Object key, Object value)
    
    ' 対処方法1
    Dim ht As New Hashtable
    ht.Add("a", 100)
    If Not ht.ContainsKey("a") Then
        ht.Add("a", 200)
    End If
    
    ' 対処方法2
    ht("a") = 100
    ht("a") = 200
    
  •  ハッシュテーブルは、一意のキーを元にして、対応する値を返す機能なので、キー値には、重複する値を登録することはできません。 対処方法は、キー値の登録チェック処理を事前に実施する、インデックス指定して値をセットする、という別案があります。


  • Dictionary
  • Dim dic As New Dictionary(Of Integer, String)
    dic.Add(1, "a")
    dic.Add(1, "b")
    
    ' 例外エラー
    System.ArgumentException: 同一のキーを含む項目が既に追加されています。
       場所 System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
       場所 System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
       場所 System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
    
    ' 対処方法1
    Dim dic As New Dictionary(Of Integer, String)
    dic.Add(1, "a")
    If Not dic.ContainsKey(1) Then
        dic.Add(1, "b")
    End If
    
    ' 対処方法2
    dic(1) = "a"
    dic(1) = "b"
    
  •  こちらも、ハッシュテーブルの事例と同様です。


  • File.ReadAllText
  • Imports System.IO
    
    Dim logFile As String = ""
    Dim logData As String = File.ReadAllText(logFile)
    
    ' 例外エラー
    System.ArgumentException: パス名を空にすることはできません。
       場所 System.IO.File.ReadAllText(String path)
    
    ' 対処方法
    Imports System.IO
    
    Dim logFile As String = ""
    If File.Exists(logFile) Then
        Dim logData As String = File.ReadAllText(logFile)
    End If
    
  •  メソッドに引数を渡す前に、その引数が妥当な値になっているかどうかの、事前チェックを挟む対処方法です。 ここでは、ファイルの存在チェックだけを実施していますが、さらに拡張子チェックも追加して厳格に確認するのも有効な手です。


  • Directory.GetDirectories
  • Imports System.IO
    
    Dim targetFolder As String = ""
    Dim subFolders() As String = Directory.GetDirectories(targetFolder)
    
    ' 例外エラー
    System.ArgumentException: パスの形式が無効です。
       場所 System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
       場所 System.IO.Path.GetFullPathInternal(String path)
       場所 System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
       場所 System.IO.Directory.GetDirectories(String path)
    
    ' 対処方法
    前の事例の対処方法と同様(フォルダパスの存在チェックを実施)
    
  •  メソッドにフォルダパスを渡す場合も、同様にフォルダの存在チェックを実施することで回避可能です。


  • Bitmap、1つ目
  • Dim imageFile As String = ""
    Me.PictureBox1.Image = New Bitmap(imageFile)
    
    ' 例外エラー
    System.ArgumentException: パスの形式が無効です。
       場所 System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
       場所 System.IO.Path.GetFullPathInternal(String path)
       場所 System.IO.Path.GetFullPath(String path)
       場所 System.Drawing.IntSecurity.UnsafeGetFullPath(String fileName)
       場所 System.Drawing.IntSecurity.DemandReadFileIO(String fileName)
       場所 System.Drawing.Bitmap..ctor(String filename)
    
    ' 対処方法
    前の事例の対処方法と同様(ファイルパスの存在チェックを実施)
    
  •  画像ファイルの場合も同様です。ファイルの存在チェックを実施することで回避可能です。


  • Bitmap、2つ目
  • Dim imageFile As String = "C:\Temp"
    Me.PictureBox1.Image = New Bitmap(imageFile)
    
    ' 例外エラー
    System.ArgumentException: 使用されたパラメーターが有効ではありません。
       場所 System.Drawing.Bitmap..ctor(String filename)
    
    ' 対処方法
    前の事例の対処方法と同様(ファイルパスの存在チェックを実施)
    
  •  画像ファイルのパスではなく、画像ファイルを格納しているフォルダのパスを渡してしまった、という場合です。 フォルダが実在するパスであっても、画像ファイルではないので、ファイルの存在チェックを挟みます。 さらに一歩踏み込んで親切な対処方法にするなら、「画像ファイルではなくフォルダを指定していますよ。」 というような、「間違った操作に気づかせる」旨のメッセージを表示します。


  • Bitmap、3つ目
  • Dim imageFile As String = "C:\Temp\sample.jpg"
    Me.PictureBox1.Image = New Bitmap(imageFile)
    
    ' 例外エラー
    System.ArgumentException: 使用されたパラメーターが有効ではありません。
       場所 System.Drawing.Bitmap..ctor(String filename)
    
    ' 対処方法
    前の事例の対処方法と同様(ファイルパスの存在チェックを実施)
    
  •  画像ファイルのパスではありますが、その画像ファイルが実際には存在しなかった場合です。 フォルダパスが違う、画像ファイル名が違う、前の処理で、画像ファイルを未作成のままだった、等が考えられます。 また、画像ファイルが実在しているのに例外エラーが発生する場合は、その画像ファイルのアクセス権設定をエクスプローラ等で確認してみてください。 アクセス権設定が拒否設定になっている場合も例外エラーが発生します。

  •  最後までこの記事を読んでいただき、ありがとうございました。

  • スポンサーリンク