2016-12-22 10 views
-1

なぜマクロが言語に含まれていなかったのか理解しています。彼らは容易に虐待されることがあります。しかし、私はいつも彼らが望ましいように見える状況に直面します。つい最近私は、画像ファイルをログに記録する方法を書いていた:Cでマクロをエミュレートする適切な方法は何ですか?

public void LogImage(Bitmap image, string name) 
{ 
    image.Save(LogRootDirectory + name + ".bmp"); 
} 

はその後、私はそれが巧妙な、より良い私がログインしていた画像に関する情報を提供することがNameOf()機能を利用することを考えました。私のコードでのいくつかの場所では、私はこれに非常に似てラインがあります。

ImageLogger?.LogImage(processedImage, nameof(processedImage)); 

私を気に何をこれの反復であり、私はずっとこれに似プリプロセッサコマンドを好む:

#define LOGIMAGE(img) ImageLogger?.LogImage(img, nameof(img)); 

上のマクロの動作をエミュレートしてコードを効率化する方法はありますか?

注:This質問は、プロセッサごとの定義がC#に存在するかどうかを質問するという点で異なります。私は彼らがしないことを私が知っていることを最初から明確にした主張。私の質問は、私が代わりに使うかもしれない技術に関連しています。私が信じているのは、マークされた答えで私に与えられたものです。

+0

プリプロセッサの[C#マクロ定義]の複製があります。(http://stackoverflow.com/questions/709463/c-sharp-macro-definitions-in-preprocessor) – phuzi

+0

C#はマクロをサポートしていません。 Visual Studioのスニペット – phuzi

+0

は上記の場合、単にLogImage(imager、nameof(image))と呼ばれるオーバーロードされたメソッドvoid LogImage(Bitmap image)を提供できませんか? –

答えて

1

C#でコンパイル時の巧妙さが失われている場合は、式のツリーを十分に酷使していないだけです。

public void LogImage(Expression<Func<Bitmap>> b) { 
    var memberExpression = b.Body as MemberExpression; 
    if (memberExpression == null) throw new ArgumentException("Must be invoked with a member reference."); 
    string name = memberExpression.Member.Name; 
    Bitmap bitmap = b.Compile()(); 
    LogImage(bitmap, name); 
} 

が、これは賢いですが、それが何かにではありませんのでLogImageは、呼び出されない場合であっても、呼び出しサイトで式ツリーを生成に伴うオーバーヘッドのビットがあり

ImageLogger?.LogImage(() => processedImage); 

として呼び出されます使い過ぎる。また、ビットマップにはという名前(getMyProcessedImage()は動作しません)が必要です。これは、C#でサポートされている場合(つまり、nameof(getMyProcessedImage())は無効です)、まったく問題があります実行時までの例外。それで、安全面でもそれほど暑いわけではありません。

個人的には、名前をもう一度入力するだけです。私は実際にnameofを使用しないでしょう。変数名の下に画像を記録することは、私にとっては疑わしい練習のようです。単にもちろん

ImageLogger?.LogImage(processedImage); 

、このとして

public void LogImage(
    Bitmap b, 
    [CallerFilePath] string filePath = "", 
    [CallerLineNumber] int lineNumber = 0 
) { 
    LogImage(b, $"{Path.GetFileNameWithoutExtension(filePath)}({lineNumber})"); 
} 

呼び出し:I は、ビットマップが生成されたソースに場所への明確な言及をしたいなかった場合、私は、発信者の情報を使用したいですは、それぞれの場所に固有のビットマップが必要だと仮定していますが、適切な前提と思われる "logger"という名前が与えられています。

+0

うん、かなりこれ。ありがとう。 –

0

匿名型で自動的にプロパティ名が生成されるという事実を利用することができます。最初のように過負荷を定義します。

public void LogImage(object obj) 
{ 
    var prop = obj.GetType().GetProperties()[0]; 
    string name = prop.Name; 
    Bitmap bitmap = (Bitmap)prop.GetValue(obj); 
    LogImage(bitmap, name); 
} 

あなたが画像を記録したいときに匿名型を使用してそれを呼び出す:

ImageLogger?.LogImage(new { processedImage }); 

これは、メカニズムの乱用で、生産コードで私はおそらくいただきたいですわかりやすくするために名前を2回入力することに傾いている。また、これは多くの場合、正確には機能しませんが、ここではイメージをファイルに保存することについて説明しています。したがって、小さなオブジェクトとリフレクションを割り当てる余分なコストは無視できます。

関連する問題