1/6 ページ プログラミングするなら Microsoft Visual Studio 2005 シンプルでパワフルな C# の最新版 www.defyallchallenges.jp/.net Tips (VB.NET, C#, Visual Studio...).NET Frameworkプログラミング, Visual Basic.NET, C#, Visual Studio, デプロイメントなどのTips ソースド サンプルを紹介しています 検索 Wiki 掲示板 Ads by Google C# コード C# Ajax C# SQLServer ASP Net C# At Visual Studio 購入 MSDNをお安く契約する方法はこちらフリーダイヤル 0120-350- 253 msdn.ips.co.jp/ C# プログラミング徹底解徹底解説 ITエンジニア必須の充実 IT 講座 100 選無料会員登録でITpro 新サービスを提供 itpro.nikkeibp.co.jp/ パート主婦主婦の給与明細旦那の給与明細女たちの給細 japanetgin.sakura.ne.jp/m プログラミング.NET Tips フォームコントロール DataGrid DataGridView ファイル フォルダ画像 印刷インターネットその他... ASP.NET 無料ホスティング Web サービスインストーラ研究メールマガジン 掲示板最新情報 ブラウザオブジェクトの NewWindow について by 鉄芯 2007/12/03(Mon) 15:38:13 検索 DOBON.NET > プログラミング道 >.NET Tips > その他の Tips 文字列の計算式計算式の計算結果計算結果を取得取得する 例えば "(1+6)*5/(7-4)" のような計算式を表す文字列から その計算結果を取得する様々な方法を紹介します 自分で解析解析するする方法 正攻法で行けば 計算式を解析し 計算するコードを自分で書くということになります そのために参考になりそうなコードは 例えば A Math Expression Evaluator です この A Math Expression Evaluator は簡単な計算はもちろん cos sin log などにも対応しています ( ただし コードは VB.NET のみです ) さらに 掲示板で ArAy さんが紹介された MSDN Japan の アルゴリズム入門 : 第 1 章 Visual C# による文字列処理入門 も参考になります このように自分でコードを書く以外の方法も様々あります JScript.NET の Eval を使用使用するする方法 Web 検索 dobon.net この方法は GotDotNet Message Boards の String to Numeric のスレッドで enderminh さんが紹介しています この方法によると まず参照に Microsoft.Jscript と Microsoft.Vsa を追加し 次のようなコードにより 計算を実行します その他 掲示板 Wiki リンク集リンクをご希望の方へ携帯専用サイト管理人にメール Translate this site into English... 広告 ' 計算式 Dim exp As String = "(1+6)*5/(7-4)" Dim ve As Microsoft.JScript.Vsa.VsaEngine = _ Microsoft.JScript.Vsa.VsaEngine.CreateEngine() Dim result As Double = _ CDbl(Microsoft.JScript.Eval.JScriptEvaluate(exp, ve)) Console.WriteLine(result) // 計算式 string exp = "(1+6)*5/(7-4)"; Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); double result =
2/6 ページ (double) Microsoft.JScript.Eval.JScriptEvaluate( exp, ve); C# プログラミング徹底解説 ITエンジニア必須の充実 IT 講座 100 選無料会員登録でITpro 新サービスを提供 itpro.nikkeibp.co.jp/ C# の転職情報リクナビNEXT 職種や地域 経験などで全国の求人情報を検索 next.rikunabi.com MSDN がお得に更新できる期限切れでも更新価格で購入可能ですマイクロソフトキャンペーン実施中! www.microsoft.com 主婦の給与振込待ち遠しい給与振込やった私の給与振込 japanetgin.sakura.ne.jp/me 他の広告を表示 VS.NET を買うなら VS2005 Pro アップグレードが 61,550 円 VB2005 EE (4,550 円 ) とアップグレードを買ったほうが新規 (122,120 円 ) より安い アップグレードについて 機能比較 VS2005 Standardアップグレードが18,580 円 新規で28,180 円 学生なら VS2005 Academic が5 千円弱 詳細 VS Tools For Office 2005 アップグレードが 63,050 円 詳細 Express Edition なら無料で使える!! * 上記の情報は 07/4/8 現在のもので 変更されている可能性があります Console.WriteLine(result); また JScriptCodeProvider により Eval メソッドを実行する方法が An Eval Function for C# using JScript.NET (JavaScript) に紹介されています この方法によると 次のようなコードがかけます 'Imports System.Reflection 'Imports System.CodeDom.Compiler ' がソースファイルの一番上に書かれているものとする ' 計算式 Dim exp As String = "(1+6)*5/(7-4)" ' 計算するためのコード Dim [source] As String = _ "package Evaluator " + vbcrlf + _ "class Evaluator " + vbcrlf + _ "public function Eval(expr : String) : String " + vbcrlf + _ "return eval(expr);}}}" ' コンパイルするための準備 Dim cp = New Microsoft.JScript.JScriptCodeProvider Dim icc As ICodeCompiler = cp.createcompiler() Dim cps As New CompilerParameters Dim cres As CompilerResults ' メモリ内で出力を生成する cps.generateinmemory = True ' コンパイルする cres = icc.compileassemblyfromsource(cps, [source]) ' コンパイルしたアセンブリを取得 Dim asm As [Assembly] = cres.compiledassembly ' クラスの Type を取得 Dim t As Type = asm.gettype("evaluator.evaluator") ' インスタンスの作成 Dim eval As Object = Activator.CreateInstance(t) 'Eval メソッドを実行し 結果を取得 Dim result As String = CStr(t.InvokeMember("Eval", _ BindingFlags.InvokeMethod, Nothing, eval, New Object() exp})) Console.WriteLine(result) //using System.Reflection; //using System.CodeDom.Compiler; // がソースファイルの一番上に書かれているものとする // 計算式 string exp = "(1+6)*5/(7-4)"; // 計算するためのコード string source = @"package Evaluator class Evaluator public function Eval(expr : String) : String
3/6 ページ }"; } } return eval(expr); // コンパイルするための準備 CodeDomProvider cp = new Microsoft.JScript.JScriptCodeProvider(); ICodeCompiler icc = cp.createcompiler(); CompilerParameters cps = new CompilerParameters(); CompilerResults cres; // メモリ内で出力を生成する cps.generateinmemory = true; // コンパイルする cres = icc.compileassemblyfromsource(cps, source); // コンパイルしたアセンブリを取得 Assembly asm = cres.compiledassembly; // クラスの Type を取得 Type t = asm.gettype("evaluator.evaluator"); // インスタンスの作成 object eval = Activator.CreateInstance(t); //Eval メソッドを実行し 結果を取得 string result = (string) t.invokemember("eval", BindingFlags.InvokeMethod, eval, new object[] exp}); Console.WriteLine(result); CSharpCodeProvider を使用使用したした方法 さらに 掲示板でピラルクさんが提案されたように CSharpCodeProvider を使って 計算式が含まれるコードの文字列をコンパイルし 実行する方法もあります この方法は Runtime Compilation (A.NET eval statement) や Evaluating Mathematical Expressions by Compiling C# Code at Runtime などでも紹介されています 具体的なコードは 例えば 次のようなものです 'Imports System.Reflection 'Imports System.CodeDom.Compiler ' がソースファイルの一番上に書かれているものとする ' 計算するためのコード Dim [source] As String = _ "public class MainClass " + vbcrlf + _ "public static double EVal() " + vbcrlf + _ "return (1d+6d)*5d/(7d-4d);" + vbcrlf + _ "}}" ' コンパイルするための準備 Dim cp = New Microsoft.CSharp.CSharpCodeProvider Dim icc As ICodeCompiler = cp.createcompiler() Dim cps As New CompilerParameters Dim cres As CompilerResults ' メモリ内で出力を生成する cps.generateinmemory = True ' コンパイルする cres = icc.compileassemblyfromsource(cps, [source])
4/6 ページ ' コンパイルしたアセンブリを取得 Dim asm As [Assembly] = cres.compiledassembly 'MainClass クラスの Type を取得 Dim t As Type = asm.gettype("mainclass") 'EVal メソッドを実行し 結果を取得 Dim d As Double = CDbl(t.InvokeMember("EVal", _ BindingFlags.InvokeMethod, Nothing, Nothing, Nothing)) Console.WriteLine(d) //using System.CodeDom.Compiler; //using System.Reflection; // がソースファイルの一番上に書かれているものとする // 計算するためのコード string source = @" public class MainClass public static double EVal() return (1d+6d)*5d/(7d-4d); } }"; // コンパイルするための準備 CodeDomProvider cp = new Microsoft.CSharp.CSharpCodeProvider(); ICodeCompiler icc = cp.createcompiler(); CompilerParameters cps = new CompilerParameters(); CompilerResults cres; // メモリ内で出力を生成する cps.generateinmemory = true; // コンパイルする cres = icc.compileassemblyfromsource(cps, source); // コンパイルしたアセンブリを取得 Assembly asm = cres.compiledassembly; //MainClass クラスの Type を取得 Type t = asm.gettype("mainclass"); //EVal メソッドを実行し 結果を取得 double d = (double) t.invokemember("eval", BindingFlags.InvokeMethod, null); Console.WriteLine(d); 前の JScript.NET の Eval を使った方法と比べると この方法は計算式をコードに含めなければならず 計算式が変わるたびにコンパイルが必要になりますし メモリのアセンブリをどのように解放するかという問題もあります ( この問題は Dynamically executing code in.net に詳しい ) そのため 実用としては困難かもしれません Microsoft Script Control を使用使用したした方法 Microsoft Script Control が使用できるならば VBScript や JSCript の Eval 関数を使う方法もあります
5/6 ページ ' 計算式 Dim exp As String = "(1+6)*5/(7-4)" Dim t As Type = _ Type.GetTypeFromProgID("MSScriptControl.ScriptControl") Dim obj As Object = Activator.CreateInstance(t) t.invokemember("language", _ System.Reflection.BindingFlags.SetProperty, _ Nothing, _ obj, _ New Object() "vbscript"}) 'Eval 関数で計算を実行して結果を取得 Dim result As Double = CDbl( _ t.invokemember("eval", _ System.Reflection.BindingFlags.InvokeMethod, _ Nothing, _ obj, _ New Object() exp})) Console.WriteLine(result) // 計算式 string exp = "(1+6)*5/(7-4)"; Type t = Type.GetTypeFromProgID("MSScriptControl.ScriptControl"); object obj = Activator.CreateInstance(t); t.invokemember("language", System.Reflection.BindingFlags.SetProperty, obj, new object[] "vbscript"}); //Eval 関数で計算を実行して結果を取得 double result = (double) t.invokemember("eval", System.Reflection.BindingFlags.InvokeMethod, obj, new object[] exp}); Console.WriteLine(result); その他の方法 これ以外にも DataTable.Compute メソッドを使う方法など まだまだありそうですが きりが無いので この辺で終わりにします ( 面白い方法がありましたら ご連絡ください ) ( この記事は.NET プログラミング研究第 34 号 で紹介したものです ) 注意 : この記事では 基本的な事柄の説明が省略されているかもしれません 初心者の方は 特に以下の点にご注意ください コードの先頭に記述されている Imports??? がソースファイルの一番上に書かれているものとする (C# では using???; がソースファイルの一番上に書かれているものとする ) の意味が分からないという方は こちらをご覧ください??? を参照に追加します の意味が分からないという方は こちらをご覧
6/6 ページ ください この記事記事へのへの評価 この記事が 役に立った 人に勧められる すばらしいと思う方は 良い を 役に立たなかった いまいち 消えてなくなれと思う方は 悪い を選択して 送信 をクリックしてください この記事への今までの評価はこちら 各 Tips の評価一覧はこちら 良い 悪い この記事記事へのへのコメント この記事に関するごく簡単なコメントを残すことが出来ます 通常のご投稿 ご質問 ご意見等は掲示板へ この記事への今までのコメントはこちら.NET Framework 2.0 以降に関するする情報 明記のない場合 この記事の全てまたは一部は.NET Framework 1.1 以前についてのみ述べられている可能性があります.NET Framework 2.0 以降では事実と異なる内容が含まれている場合 下のボタンからご報告ください 今まで投稿された情報はこちらでご覧いただけます この記事記事へのへのトラックバック この記事にトラックバックすることができます ただしこちらの注意事項に沿わないものは遠慮なく削除させていただきます 自動トラックバックにも対応 この記事への今までのトラックバックはこちら この記事のトラックバック Ping URL : http://dobon.net/cgi-bin/tb/tb.php/programing/eval.html その他 送信 コメントを投稿する.NET Framework 2.0 以降に関する情報を投稿する Translate this page into English... この Tips の URL を電子メールで送信するこのページをブックマークに追加する Copyright 2002-2007 DOBON!. All rights reserved.