null 値
null 値 Null Values
元ネタ http://msdn.microsoft.com/ja-jp/library/dd233197.aspx
.NET のメソッドに null 値を渡すには、呼び出し元のコードで null キーワードを使用します。
F#
open System // Pass a null value to a .NET method. let ParseDateTime (str: string) = let (success, res) = DateTime.TryParse(str, null, System.Globalization.DateTimeStyles.AssumeUniversal) if success then Some(res) else None
TryParse メソッドは、パースを行って成功/失敗を bool 値を返すと同時に、成功した場合は out で値を返す。 C# の場合は、ParseDateTime メソッドで戻り値を DateTime? にして、失敗の場合は null を返すようにする
C#
public DateTime? ParseDateTime(string str) { DateTime res ; if (DateTime.TryParse(str, null, System.Globalization.DateTimeStyles.AssumeUniversal, out res)) return res; else return null; }
.NET のメソッドから取得した null 値を解釈するには、可能であればパターン マッチを使用します。 入力ストリームの末尾を超えて読み取ろうとしたときに ReadLine から返される null 値を、パターン マッチを使用して解釈する方法を次のコード例に示します。
F#
// Open a file and create a stream reader. let fileStream1 = try System.IO.File.OpenRead("TextFile1.txt") with | :? System.IO.FileNotFoundException -> printfn "Error: TextFile1.txt not found."; exit(1) let streamReader = new System.IO.StreamReader(fileStream1) // ProcessNextLine returns false when there is no more input; // it returns true when there is more input. let ProcessNextLine nextLine = match nextLine with | null -> false | inputString -> match ParseDateTime inputString with | Some(date) -> printfn "%s" (date.ToLocalTime().ToString()) | None -> printfn "Failed to parse the input." true // A null value returned from .NET method ReadLine when there is // no more input. while ProcessNextLine (streamReader.ReadLine()) do ()
F# の場合は一時的な関数をその場で書けるが、C# の場合はメソッド化しないといけない。
C#
public void test() { System.IO.FileStream fileStream1 = null; try { fileStream1 = System.IO.File.OpenRead("TextFile1.txt"); } catch ( System.IO.FileNotFoundException ex ) { Console.WriteLine("Error: TextFile1.txt not found."); return ; } var streamReader = new System.IO.StreamReader(fileStream1); // A null value returned from .NET method ReadLine when there is // no more input. while (ProcessNextLine(streamReader.ReadLine())) ; } bool ProcessNextLine(string nextLine) { switch (nextLine) { case null: return false; default: var date = ParseDateTime(nextLine); if (date != null) { Console.WriteLine("{0}", date.Value.ToLocalTime().ToString()); } else { Console.WriteLine("Failed to parse the input."); } return true; } }
ただし、必ずメソッド化しないと駄目というわけでもなく、ラムダ式を使うと似た感じで書ける。
C#
public void test2() { System.IO.FileStream fileStream1 = null; try { fileStream1 = System.IO.File.OpenRead("TextFile1.txt"); } catch (System.IO.FileNotFoundException ex) { Console.WriteLine("Error: TextFile1.txt not found."); return; } var streamReader = new System.IO.StreamReader(fileStream1); Func<string, bool> ProcessNextLine = nextLine => { switch (nextLine) { case null: return false; default: var date = ParseDateTime(nextLine); if (date != null) { Console.WriteLine("{0}", date.Value.ToLocalTime().ToString()); } else { Console.WriteLine("Failed to parse the input."); } return true; } }; // A null value returned from .NET method ReadLine when there is // no more input. while (ProcessNextLine(streamReader.ReadLine())) ; }
F# の型に対する null 値は、Unchecked.defaultof を呼び出す Array.zeroCreate を使用する場合など、別の方法でも生成されることがあります。
F#
match box value with | null -> printf "The value is null." | _ -> printf "The value is not null."
box を使う必要は C# ではないと思われる。