F# プロジェクト内では C# のコードが利用できないので C# から F# に変換できたら良いですね。 F# PowerPack には CodeDOM の実装があるのでこれを使えば良さそうです。
CodeDOM を使って C# のコードを F# に変換するためにはまず C# のコードを CodeCompileUnit に落とし込む必要があります。 CodeCompileUnit 形式のオブジェクトは次のように F# のコードに変換できます。
let fsharpCode compileUnit = use provider = new FSharpCodeProvider () let options = CodeGeneratorOptions (IndentString = " ") let builder = StringBuilder () use writer = new StringWriter (builder) provider.GenerateCodeFromCompileUnit (compileUnit, writer, options) builder.ToString ()
インデントが 3 スペースなのは完全に趣味です。
C# のコードを CodeCompileUnit にするには CSharpCodeProvider.Parse メソッドを使えば良いように見えますが, NotImplementedException が投げられます。そこで NRefactory を用います。
let compileUnit csharpSourcePath =
let compilation =
let projectContent = CSharpProjectContent ()
SimpleCompilation (projectContent)
let syntaxTree =
let parser = CSharpParser ()
use reader = new StreamReader (csharpSourcePath)
parser.Parse (reader)
let visitor = CodeDomConvertVisitor ()
visitor.Convert (compilation, syntaxTree, null)
例えば次の C# コードを変換します。
using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello, World!");
}
}
結果は次のようになります。
//------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------
namespace global
namespace global
// Generated by F# CodeDom
#nowarn "49" // uppercase argument names
#nowarn "67" // this type test or downcast will always hold
#nowarn "66" // this upcast is unnecessary - the types are identical
#nowarn "58" // possible incorrect indentation..
#nowarn "57" // do not use create_DelegateEvent
#nowarn "51" // address-of operator can occur in the code
#nowarn "1183" // unused 'this' reference
exception ReturnException3b9ed1539eac46fc9190777a400ea3c7 of obj
exception ReturnNoneException3b9ed1539eac46fc9190777a400ea3c7
[<AutoOpen>]
module FuncConvertFinalOverload3b9ed1539eac46fc9190777a400ea3c7 =
// This extension member adds to the FuncConvert type and is the last resort member in the method overloading rules.
type global.Microsoft.FSharp.Core.FuncConvert with
/// A utility function to convert function values from tupled to curried form
static member FuncFromTupled (f:'T -> 'Res) = f
type
Program = class
new() as this =
{
}
static member Main () =
Console.WriteLine("Hello, World!") |> ignore
end
System 名前空間が open されていなかったり, Main メソッドが EntryPoint でなかったりして,残念ながら完全とはいえません。しかし,一から書き直すよりは大分負担が少ないのではないでしょうか。