ArgumentException について

初級者向けにおさらいします。

目次

この例外エラーの説明

Argument(メソッドに渡されてきた引数が、無効な値だった場合に発生する)Exception です。

事例とその対処方法

例外エラーは、想定外の扱われ方をすると発生して飛んで来ます。それは命令の使い方が間違っていたり、存在しないデータを扱おうとしていたり、アカウント権限を越えたアクセスをしようとしていたり(Windows 側やウェブ側の話だったり)、サービスが動いていないのに連携しようとしたり、製品上の仕様考慮モレだったり、そういう系です。

こうなっている前提のはずだから、こうやろうとしたのに、実際はここがこうなっているからダメじゃん!こういう場合の処理が無いじゃん!みたいなコードになっていませんか?

DataTable

メモリ上のデータベースである DataTable で、存在しない列名を指定してしまう事例です。

Dim dt As New DataTable
dt.Columns.Add("No", GetType(Integer))
dt.Columns.Add("Name", GetType(String))
dt.Rows.Add(New Object() {1, "taro"})

Dim row As DataRow = dt.Rows(0)
Dim name As String = CStr(row("Namae"))
System.ArgumentException: '列 'Namae' はテーブル  に属していません。'

System.IO.File

ファイルを読み取ろうとした際、ファイルのパスが空だった、Nothing だった、という場合です。

Dim logFile As String = ""
Dim logData As String = File.ReadAllText(logFile)
Imports System.IO

Module Module1

    Sub Main()

        Dim logFile As String = ""
        CheckAndSaveData(logFile)


        Console.ReadKey()
    End Sub

    Sub CheckAndSaveData(s As String)
        Dim logData As String = File.ReadAllText(s)
    End Sub

End Module
System.ArgumentException: 'パス名を空にすることはできません。'

こういう場合は、ファイルの存在チェックをしてから読み取ります。

Dim logFile As String = ""
If File.Exists(logFile) Then
    Dim logData As String = File.ReadAllText(logFile)
End If

または、ファイルを開くダイアログ経由で、指定してもらって開きます。

Imports System.IO
Imports System.Windows.Forms

Module Module1

    Sub Main()

        Dim logFile As String = ""
        Using dlg As New OpenFileDialog

            dlg.FileName = "*.log"
            dlg.Filter = "log ファイル(*.log)|*.log"

            Dim result = dlg.ShowDialog()
            If result <> DialogResult.OK Then
                Return
            End If
            logFile = dlg.FileName

        End Using

        Dim logData As String = File.ReadAllText(logFile)



        Console.ReadKey()
    End Sub

End Module

ファイルもフォルダも、存在しているパスを指定しているかどうかを確認します。

Dictionary(Of TKey, TValue)

ディクショナリではキー値の重複管理はできません。一意でなくてはいけないため例外エラーが発生します。

Dim dic As New Dictionary(Of Integer, String)
dic.Add(1, "a")
dic.Add(1, "b")
System.ArgumentException: '同一のキーを含む項目が既に追加されています。'

キーと値を登録する前にキー値が登録されているかチェックしてから登録する、または上書き可能な登録方法で登録します。

Dim dic As New Dictionary(Of Integer, String)
dic.Add(1, "a")

' 登録前に存在チェック
If Not dic.ContainsKey(1) Then
    dic.Add(1, "b")
End If

' 存在している場合は上書きする方の書き方
dic(1) = "a"
dic(1) = "b"